Conversation
Add comprehensive documentation for opaque API tokens under "Add auth to your APIs" section. Covers create, validate, list, and invalidate operations with code examples in all 4 SDKs (Node.js, Python, Go, Java). Includes middleware patterns for protecting API endpoints and best practices. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add tags, error handling, security comments, collapse for init blocks, Python tuple explanation, and closing next-steps section.
… improvements - Rename opaque-tokens.mdx to api-keys.mdx, update sidebar config - Rewrite intro with Scalekit recommendation tone - Add D2 sequence diagram showing API key lifecycle flow - Split create token into org-scoped and user-scoped subsections - Add validate subsections for roles/externalOrgId and custom metadata - Reorder invalidate examples (API key first, tokenId second) - Remove framework titles from generic code examples - Replace log.Fatalf with log.Printf in Go examples - Update all prose references from opaque tokens to API keys
Update all validate token examples to catch SDK-specific exceptions (ScalekitValidateTokenFailureException, ErrTokenValidationFailed, TokenInvalidException) instead of generic Error/Exception, and add bullet-pointed intro section.
Rewrite prose sections with a warmer, more conversational tone matching the api-auth-quickstart and scopes articles. Move API keys to last position under "Add auth to your APIs" in the sidebar.
|
Note Reviews pausedIt looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the Use the following commands to manage reviews:
Use the checkboxes below for quick actions:
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review infoConfiguration used: Repository UI Review profile: CHILL Plan: Pro 📒 Files selected for processing (1)
🚧 Files skipped from review as they are similar to previous changes (1)
📝 WalkthroughWalkthroughAdded a new comprehensive API-keys doc, removed the old M2M scopes guide, updated OAuth2 quickstart and sidebar/redirects to point to the new content, and added a Git commit guideline in CLAUDE.md. No public code-level APIs changed. (50 words) Changes
Estimated code review effort🎯 4 (Complex) | ⏱️ ~45 minutes Possibly related PRs
Suggested reviewers
Poem
🚥 Pre-merge checks | ✅ 2 | ❌ 1❌ Failed checks (1 inconclusive)
✅ Passed checks (2 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Comment |
✅ Deploy Preview for scalekit-starlight ready!
To edit notification comments on pull requests, go to your Netlify project configuration. |
There was a problem hiding this comment.
Actionable comments posted: 3
🤖 Fix all issues with AI agents
In `@src/content/docs/authenticate/m2m/api-keys.mdx`:
- Around line 898-900: The "Set expiry for time-limited access" Card references
an `expiry` parameter but the "Create a token" examples don't show it; update
the create-token examples in this doc to demonstrate supplying an `expiry` value
(or add a short note linking to the API reference) so readers see how to set
time-limited keys—modify the "Create a token" code blocks near the Card titled
"Set expiry for time-limited access" to include an `expiry` field (and a brief
inline comment) or add a one-line callout that points to the API reference for
`expiry`.
- Line 23: Summary: Hyphenate the compound adjective "server side validation" to
"server-side validation". Fix: locate the sentence containing "server side
validation" in the API keys description (the sentence that reads "API Keys can
be validated via APIs with Scalekit and after server side validation...") and
replace "server side validation" with "server-side validation" so the compound
adjective is correctly hyphenated.
- Around line 179-191: The Java example for creating an organization-scoped
token omits the description parameter; update the call to
scalekitClient.tokens().create(organizationId) to pass a description string
(matching how Node/Python/Go do) so the CreateTokenResponse creation includes
the description field; locate the example using CreateTokenResponse and
scalekitClient.tokens().create(...) and add the description argument
consistently with the user-scoped token example.
🧹 Nitpick comments (1)
src/content/docs/authenticate/m2m/api-keys.mdx (1)
383-398: Missing import forScalekitValidateTokenFailureException.The exception is used in the catch block but the import statement is not shown in this code example. For consistency with line 304 and to ensure the example is complete, consider adding the import.
📝 Suggested fix
```javascript +import { ScalekitValidateTokenFailureException } from '@scalekit-sdk/node'; + try { const result = await scalekit.token.validateToken(opaqueToken);
📜 Review details
Configuration used: Repository UI
Review profile: CHILL
Plan: Pro
⛔ Files ignored due to path filters (1)
public/d2/docs/authenticate/m2m/api-keys-0.svgis excluded by!**/*.svg
📒 Files selected for processing (3)
CLAUDE.mdsrc/configs/sidebar.config.tssrc/content/docs/authenticate/m2m/api-keys.mdx
🧰 Additional context used
📓 Path-based instructions (7)
**/*.{md,mdx}
📄 CodeRabbit inference engine (CLAUDE.md)
**/*.{md,mdx}: All code examples must include implementations in all 4 languages: Node.js, Python, Go, and Java
Include security comments in code examples explaining security threats and implications
Code examples must demonstrate both success and error paths
Frontmatter must include: title (≤60 characters), description (≤160 characters), sidebar label, order number, and tags array
Use second person ('you', 'your application') for writing voice in documentation
Use present tense for descriptions and imperative mood for instructions in documentation
**/*.{md,mdx}: Use sentence case for all titles and headings in MD/MDX documentation
Keep page titles short and descriptive (3–7 words when possible) in MD/MDX documentation
Use outcome-focused headings that describe results, not categories (e.g., 'Run a script' not 'Scripts')
Avoid gerunds in headings when an imperative works - prefer 'Configure proxies' over 'Configuring proxies'
Keep sidebar labels concise (1–3 words), use sentence case, and focus on outcomes or objects
Use sentence case in sidebar labels without punctuation
Set frontmatter title in sentence case with a clear outcome; description in one sentence (≤160 chars); sidebar.label as shorter form of title; enable tableOfContents on longer pages
Start documentation pages with a one-paragraph overview explaining what the page covers and when to use it
Present the primary use case (80% path) first in documentation, with edge cases later
Use numbered steps for task-focused sections in documentation, with each step beginning with a verb
Break up long documentation sections with subheadings every 3–6 paragraphs
Use asides for important notes, tips, cautions, and references in documentation
Provide runnable, minimal code examples that work as-is in documentation
Prefer CLI-first examples and show file layout when helpful in documentation
Label code blocks with titles for context (e.g., 'Terminal', 'main.ts') in documentation
Keep code block annotations brief and...
Files:
CLAUDE.mdsrc/content/docs/authenticate/m2m/api-keys.mdx
**/*.{yml,yaml,md,mdx}
📄 CodeRabbit inference engine (.cursor/rules/browsecentral-labels.mdc)
**/*.{yml,yaml,md,mdx}: BrowseCentral labels should be maximum 3-5 words - keep concise but add context when needed
BrowseCentral labels should be action-oriented - start with verbs when possible
BrowseCentral labels should be specific and clear - add context when simple labels are ambiguous
BrowseCentral labels should be outcome-focused - describe what users accomplish and the context
BrowseCentral labels should use 'Action + Object' pattern (e.g., 'Invite users', 'Restrict sign-up', 'Set up SCIM')
BrowseCentral labels should use feature names (e.g., 'Enterprise SSO', 'Passwordless quickstart')
BrowseCentral labels should describe task completion (e.g., 'Run migrations', 'Migrate auth', 'Merge identities')
BrowseCentral labels should include specific context when needed (e.g., 'Configure Scalekit MCP server', 'Validate incoming API requests')
BrowseCentral labels should use integration context when applicable (e.g., 'Build MCP auth with your existing auth system')
BrowseCentral labels should avoid instructional prefixes: 'How to', 'Guide to', 'Implement', 'Configure', 'Learn', 'Understand'
BrowseCentral labels should avoid verbose phrases: 'Step-by-step guide', 'Complete tutorial', 'Detailed documentation'
BrowseCentral labels should avoid weak verbs: 'Enable', 'Allow', 'Provide', 'Support'
Files:
CLAUDE.mdsrc/content/docs/authenticate/m2m/api-keys.mdx
**/*.mdx
📄 CodeRabbit inference engine (.cursorrules)
**/*.mdx: Use clear, descriptive titles that explain the purpose of the document
Include comprehensive descriptions in frontmatter metadata
Organize content with logical heading hierarchy (H2, H3, H4)
Use tableOfContents property in frontmatter when content has multiple sections
Set appropriate sidebar labels for navigation in frontmatter
Use direct instruction writing style with phrases like 'This guide shows you how to...' and 'Create an authorization URL to...'
Use second person perspective ('your application', 'you receive', 'you must') in documentation
Keep sentences concise, aiming for under 25 words per sentence
Explain the 'why' in documentation with phrases like 'This prevents CSRF attacks by...' or 'Use this to validate that...'
Use action verbs in section headings: 'Store session tokens securely', 'Validate the state parameter', 'Exchange authorization code for tokens'
Use present tense for descriptions: 'Scalekit handles the complex authentication flow', 'The SDK provides methods to refresh tokens'
Use future tense for results: 'This will redirect users to...', 'You'll receive a JWT containing...', 'Scalekit returns an authorization code'
Use transition phrases between sections: 'After the user authenticates...', 'Once the state is validated...', 'Let's take a look at how to...'
Write 1-3 opening paragraphs that explain what users will accomplish, provide context about when/why, preview key concepts, and use direct instructional language
Begin introduction sections with a clear statement of what the guide covers and explain the problem being solved
Use collapsible sections in introduction for sequence diagrams, video demonstrations, data models, and JSON examples with appropriate icons
Use numbered format within Steps component:1. ## Titlewith all step content indented with exactly 3 spaces
Use action-oriented headings in step-by-step guides within Steps components
Include code examples in all 4 languages (Node.js, Python, Go, Java) within Steps co...
Files:
src/content/docs/authenticate/m2m/api-keys.mdx
**/*.{js,ts,py,go,java,tsx,jsx}
📄 CodeRabbit inference engine (CLAUDE.md)
SDK variable names must follow language-specific conventions: Node.js uses
scalekit, Python usesscalekit_client, Go usesscalekitClient, Java usesscalekitClient
Files:
src/configs/sidebar.config.ts
**/*.{js,ts,tsx,jsx,py,java,cs,go,cpp,c,rb,php,swift,kt,scala,rs,m,mm,groovy,gradle,xml,json}
📄 CodeRabbit inference engine (.cursor/rules/comment-standards.mdc)
Comments should not duplicate the code - avoid comments that simply restate what the code does; comments should add value beyond what's obvious from reading the code
Files:
src/configs/sidebar.config.ts
**/*.{js,ts,tsx,jsx,py,java,cs,go,cpp,c,rb,php,swift,kt,scala,rs,m,mm,groovy}
📄 CodeRabbit inference engine (.cursor/rules/comment-standards.mdc)
**/*.{js,ts,tsx,jsx,py,java,cs,go,cpp,c,rb,php,swift,kt,scala,rs,m,mm,groovy}: Good comments do not excuse unclear code - refactor the code to be self-explanatory instead of using comments to explain poorly written code; use better variable names, function names, and code structure
Comments should dispel confusion, not cause it - ensure comments clarify rather than obscure the code's purpose; avoid cryptic or joke comments
Explain unidiomatic code in comments - comment on code that might seem unnecessary or redundant and document why you chose a specific pattern over more common alternatives, especially when it deviates from team conventions
Provide links to the original source of copied code - always attribute code copied from external sources with URLs to Stack Overflow answers, GitHub repositories, or documentation
Include links to external references where helpful - reference standards, RFCs, and official documentation; link to relevant specifications when implementing protocols
Add comments when fixing bugs - document bug fixes with context about the issue, reference issue trackers and bug reports, and explain workarounds and their limitations
Use comments to mark incomplete implementations - use standard formats for TODO, FIXME, and NOTE comments with context about what needs to be done and reference issue trackers when possible
Always document public APIs with function/class comments - explain the purpose, parameters, return values, and exceptions; include usage examples for complex functions
Include file headers with copyright information, license, and authorship - provide a brief description of the file's purpose and document dependencies and requirements
Files:
src/configs/sidebar.config.ts
**/*.{js,ts,tsx,jsx}
📄 CodeRabbit inference engine (.cursor/rules/comment-standards.mdc)
Use JSDoc standards for all function, class, and complex logic comments in JavaScript/TypeScript - include parameter descriptions (
@param), return values (@returns), types (@type), and descriptions; document exceptions and edge cases
Files:
src/configs/sidebar.config.ts
🧠 Learnings (9)
📓 Common learnings
Learnt from: saif-at-scalekit
Repo: scalekit-inc/developer-docs PR: 424
File: public/api/scalekit.scalar.json:3451-3457
Timestamp: 2026-02-10T05:32:59.967Z
Learning: In scalekit-inc/developer-docs, the file public/api/scalekit.scalar.json is a generated OpenAPI artifact; reviewers should avoid direct edits. For inconsistencies (e.g., the /api/v1/permissions "type" query param description vs. enum), handle short-term via release/PR notes and track long-term fixes in the generator or source templates rather than modifying the generated JSON.
📚 Learning: 2026-01-13T12:47:04.673Z
Learnt from: CR
Repo: scalekit-inc/developer-docs PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-01-13T12:47:04.673Z
Learning: Applies to **/*.{js,ts,py,go,java,tsx,jsx} : SDK variable names must follow language-specific conventions: Node.js uses `scalekit`, Python uses `scalekit_client`, Go uses `scalekitClient`, Java uses `scalekitClient`
Applied to files:
CLAUDE.md
📚 Learning: 2026-01-13T12:46:55.260Z
Learnt from: CR
Repo: scalekit-inc/developer-docs PR: 0
File: .cursorrules:0-0
Timestamp: 2026-01-13T12:46:55.260Z
Learning: Applies to **/*.mdx : Use consistent SDK variable naming: Node.js='scalekit', Python='scalekit_client', Go='scalekitClient', Java='scalekitClient'
Applied to files:
CLAUDE.md
📚 Learning: 2026-02-10T05:32:59.967Z
Learnt from: saif-at-scalekit
Repo: scalekit-inc/developer-docs PR: 424
File: public/api/scalekit.scalar.json:3451-3457
Timestamp: 2026-02-10T05:32:59.967Z
Learning: In scalekit-inc/developer-docs, the file public/api/scalekit.scalar.json is a generated OpenAPI artifact; reviewers should avoid direct edits. For inconsistencies (e.g., the /api/v1/permissions "type" query param description vs. enum), handle short-term via release/PR notes and track long-term fixes in the generator or source templates rather than modifying the generated JSON.
Applied to files:
CLAUDE.mdsrc/content/docs/authenticate/m2m/api-keys.mdx
📚 Learning: 2026-01-13T12:46:55.260Z
Learnt from: CR
Repo: scalekit-inc/developer-docs PR: 0
File: .cursorrules:0-0
Timestamp: 2026-01-13T12:46:55.260Z
Learning: Applies to **/*.mdx : Use present tense for descriptions: 'Scalekit handles the complex authentication flow', 'The SDK provides methods to refresh tokens'
Applied to files:
CLAUDE.md
📚 Learning: 2026-02-02T05:55:51.251Z
Learnt from: AkshayParihar33
Repo: scalekit-inc/developer-docs PR: 415
File: src/content/docs/authenticate/fsa/multiapp/native-app.mdx:72-179
Timestamp: 2026-02-02T05:55:51.251Z
Learning: In the `src/content/docs/authenticate/fsa/multiapp/` directory, the multi-app authentication documentation (native-app.mdx, single-page-app.mdx, web-app.mdx, overview.mdx) currently uses conceptual shell/curl examples instead of multi-language SDK code examples because the Scalekit SDKs have not yet been built/updated for multi-app functionality. Once the SDKs are ready, these files should be updated to include all 4 languages (Node.js, Python, Go, Java) using `<Tabs syncKey="tech-stack">`.
Applied to files:
src/content/docs/authenticate/m2m/api-keys.mdxsrc/configs/sidebar.config.ts
📚 Learning: 2026-01-30T18:18:50.883Z
Learnt from: AkshayParihar33
Repo: scalekit-inc/developer-docs PR: 415
File: src/content/docs/authenticate/fsa/multiapp/manage-apps.mdx:31-49
Timestamp: 2026-01-30T18:18:50.883Z
Learning: In all Scalekit documentation files (MDX), treat the terms 'Applications', 'Single Page Application (SPA)', 'Native Application', and 'Web Application' as proper nouns and preserve their capitalization in headings and body text. Ensure these terms remain capitalized even when used in sentence case or within prose.
Applied to files:
src/content/docs/authenticate/m2m/api-keys.mdx
📚 Learning: 2026-02-04T12:47:16.544Z
Learnt from: saif-at-scalekit
Repo: scalekit-inc/developer-docs PR: 412
File: src/content/docs/dev-kit/tools/scalekit-dryrun.mdx:1-23
Timestamp: 2026-02-04T12:47:16.544Z
Learning: In scalekit-inc/developer-docs, the MDX frontmatter field order is required only when the sidebar configuration points to a directory (for auto-generation). If the sidebar.config.ts references a specific file path, the order field is not required. Apply this check to all MDX files under src/content/docs: if a file contributes to an auto-generated sidebar (directory path), ensure order is present; if it’s linked to a concrete file, order can be omitted. Use sidebar.config.ts to determine whether a given MDX file falls under directory-based vs file-specific sidebar references.
Applied to files:
src/content/docs/authenticate/m2m/api-keys.mdx
📚 Learning: 2026-01-30T18:20:07.851Z
Learnt from: AkshayParihar33
Repo: scalekit-inc/developer-docs PR: 415
File: src/content/docs/authenticate/fsa/multiapp/native-app.mdx:1-6
Timestamp: 2026-01-30T18:20:07.851Z
Learning: In the scalekit-inc/developer-docs repository, MDX files under `src/content/docs/authenticate/fsa/multiapp/` do not use `order` or `tags` fields in their frontmatter. Ordering and grouping are managed centrally in `src/configs/sidebar.config.ts`.
Applied to files:
src/configs/sidebar.config.ts
🪛 LanguageTool
src/content/docs/authenticate/m2m/api-keys.mdx
[grammar] ~23-~23: Use a hyphen to join words.
Context: ... via APIs with Scalekit and after server side validation, the claims are sent whe...
(QB_NEW_EN_HYPHEN)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
- GitHub Check: Redirect rules - scalekit-starlight
- GitHub Check: Header rules - scalekit-starlight
- GitHub Check: Pages changed - scalekit-starlight
🔇 Additional comments (4)
CLAUDE.md (1)
36-38: LGTM!The addition of the Git Commits reminder is clear and follows the existing structure of the Key Reminders section.
src/configs/sidebar.config.ts (1)
71-71: LGTM!The new sidebar entry is correctly placed within the "Add auth to your APIs" section, logically following the API auth quickstart and scopes documentation.
src/content/docs/authenticate/m2m/api-keys.mdx (2)
718-888: Well-structured middleware examples with comprehensive security comments.The middleware patterns are consistently implemented across all four languages, with clear security comments explaining the rationale for each check. The examples are complete and demonstrate both authentication and authorization context handling.
1-911: Comprehensive and well-structured API keys documentation.This guide thoroughly covers the API keys lifecycle with consistent multi-language examples, appropriate security comments, and clear explanations. The D2 sequence diagram, middleware patterns, and best practices section add significant value for developers implementing API key authentication.
✏️ Tip: You can disable this entire section by setting review_details to false in your review settings.
| ```java | ||
| try { | ||
| CreateTokenResponse response = scalekitClient.tokens().create(organizationId); | ||
|
|
||
| // Store securely — this value cannot be retrieved again after creation | ||
| String opaqueToken = response.getToken(); | ||
| // Stable identifier for management operations (format: apit_xxxxx) | ||
| String tokenId = response.getTokenId(); | ||
| } catch (Exception e) { | ||
| System.err.println("Failed to create token: " + e.getMessage()); | ||
| } | ||
| ``` | ||
|
|
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
# First, let's check the file structure and context around the disputed code
fd "api-keys.mdx" --type fRepository: scalekit-inc/developer-docs
Length of output: 117
🏁 Script executed:
# Check the exact content of the file around lines 179-191 and the surrounding examples
cat -n src/content/docs/authenticate/m2m/api-keys.mdx | sed -n '150,220p'Repository: scalekit-inc/developer-docs
Length of output: 2467
🏁 Script executed:
# Search for Java SDK implementation or type definitions that might show the create method signature
find . -type f -name "*.java" -o -name "*.ts" -o -name "*.js" -o -name "*.json" | head -20Repository: scalekit-inc/developer-docs
Length of output: 693
🏁 Script executed:
# Look for SDK documentation or type definitions within the repo
fd -e ts -e d.ts | xargs rg "create.*organizationId" -A 3 -B 1 2>/dev/null | head -50Repository: scalekit-inc/developer-docs
Length of output: 53
🏁 Script executed:
# Get earlier lines to see the Node.js and Python examples
cat -n src/content/docs/authenticate/m2m/api-keys.mdx | sed -n '120,160p'Repository: scalekit-inc/developer-docs
Length of output: 1445
🏁 Script executed:
# Search for Java SDK type definitions or examples in the codebase
find . -type f \( -name "*.java" -o -name "*.ts" -o -name "*.d.ts" \) | xargs rg "CreateTokenResponse|tokens.*create" 2>/dev/null | head -30Repository: scalekit-inc/developer-docs
Length of output: 53
🏁 Script executed:
# Check if there's SDK documentation or OpenAPI spec that describes the Java SDK
fd -e json -e yaml -e yml | xargs rg "CreateToken|create.*token" 2>/dev/null | head -20Repository: scalekit-inc/developer-docs
Length of output: 950
🏁 Script executed:
# Search for any references to the Java SDK's create method parameters
rg "scalekitClient.*tokens.*create" --type mdx -A 5 -B 5Repository: scalekit-inc/developer-docs
Length of output: 98
🏁 Script executed:
# Look for the Java SDK create token method in the OpenAPI spec
rg "CreateToken|create.*token" public/api/scalekit.scalar.json -A 10 | head -100Repository: scalekit-inc/developer-docs
Length of output: 2803
🏁 Script executed:
# Check if there's a postman collection with example requests
rg "create.*token\|CreateToken" public/api/scalekit.postman_collection.json -A 5 -B 2 | head -50Repository: scalekit-inc/developer-docs
Length of output: 53
🏁 Script executed:
# Search the documentation for any other Java examples that show the create method with parameters
cat src/content/docs/authenticate/m2m/api-keys.mdx | grep -A 10 "java" | grep -A 10 "create"Repository: scalekit-inc/developer-docs
Length of output: 1512
Java example omits description parameter inconsistently with other language examples.
The Node.js, Python, and Go examples all pass a description parameter when creating organization-scoped tokens, but the Java example doesn't include it. The Java SDK clearly supports this parameter (as shown in the user-scoped token example below), making this an inconsistency that should be addressed for clarity.
📝 Suggested fix
try {
- CreateTokenResponse response = scalekitClient.tokens().create(organizationId);
+ CreateTokenResponse response = scalekitClient.tokens().create(
+ organizationId, null, null, null, "CI/CD pipeline token"
+ );
// Store securely — this value cannot be retrieved again after creation🤖 Prompt for AI Agents
In `@src/content/docs/authenticate/m2m/api-keys.mdx` around lines 179 - 191, The
Java example for creating an organization-scoped token omits the description
parameter; update the call to scalekitClient.tokens().create(organizationId) to
pass a description string (matching how Node/Python/Go do) so the
CreateTokenResponse creation includes the description field; locate the example
using CreateTokenResponse and scalekitClient.tokens().create(...) and add the
description argument consistently with the user-scoped token example.
| <Card title="Set expiry for time-limited access"> | ||
| Use the `expiry` parameter for keys that should automatically become invalid after a set period. This limits the blast radius if a key is compromised. | ||
| </Card> |
There was a problem hiding this comment.
Best practice references undocumented expiry parameter.
The "Set expiry for time-limited access" card mentions using the expiry parameter, but this parameter is not demonstrated in the "Create a token" code examples. Consider adding an example showing how to set token expiry, or clarifying that this feature exists and linking to API reference.
Would you like me to draft an example showing how to use the expiry parameter in the create token examples?
🤖 Prompt for AI Agents
In `@src/content/docs/authenticate/m2m/api-keys.mdx` around lines 898 - 900, The
"Set expiry for time-limited access" Card references an `expiry` parameter but
the "Create a token" examples don't show it; update the create-token examples in
this doc to demonstrate supplying an `expiry` value (or add a short note linking
to the API reference) so readers see how to set time-limited keys—modify the
"Create a token" code blocks near the Card titled "Set expiry for time-limited
access" to include an `expiry` field (and a brief inline comment) or add a
one-line callout that points to the API reference for `expiry`.
|
Do not merge yet, I will come back to do a few updates. |
…nology and enhance clarity - Changed the title from "Add auth to your APIs" to "Add OAuth2.0 to your APIs" for specificity. - Revised introductory content to clarify the role of APIs and the importance of OAuth 2.0 for client credentials authentication. - Improved the description of the API client registration process, emphasizing customer interaction and Scalekit integration. - Added details on API client scopes and their validation, enhancing security context. - Included collapsible sections for sample responses to improve readability and organization. This update aligns the documentation with current standards and enhances user understanding of OAuth 2.0 integration.
There was a problem hiding this comment.
Actionable comments posted: 6
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (3)
src/content/docs/authenticate/m2m/api-auth-quickstart.mdx (3)
2-23:⚠️ Potential issue | 🟠 MajorAdd required frontmatter metadata and make the BrowseCentral label action‑oriented.
This page has multiple sections but lacks
tableOfContents, and there’s notagsarray. Also, the BrowseCentral label should start with a verb, and the title should use “OAuth 2.0”.✏️ Suggested frontmatter update
-title: Add OAuth2.0 to your APIs +title: Add OAuth 2.0 to your APIs description: "Secure your APIs in minutes with OAuth 2.0 client credentials, scoped access, and JWT validation using Scalekit" browseCentral: - label: "API authentication with M2M OAuth" + label: "Authenticate APIs with M2M OAuth" filterType: ["tutorial"] category: ["Auth modules"] icon: book +tags: [oauth2, m2m, api-auth, client-credentials] +tableOfContents: true sidebar: label: "Add OAuth 2.0"As per coding guidelines: “Frontmatter must include: title (≤60 characters), description (≤160 characters), sidebar label, order number, and tags array” and “Use tableOfContents property in frontmatter when content has multiple sections.” Also: “BrowseCentral labels should be action-oriented - start with verbs when possible.”
28-43:⚠️ Potential issue | 🟡 MinorFix grammar and typos in the introduction and diagram.
Several small errors reduce clarity (its/it’s, “OAuth 2.0-based”, “Here’s how it works”, and “credentials”).
✏️ Suggested edits
-APIs are a way to let your customers, partners, and external systems interact with your application and it's data. It requires authentication to ensure only authorized clients can consume your APIs. Scalekit provides a way to add OAuth2.0 based client credentials authentication to your API endpoints. +APIs are a way to let your customers, partners, and external systems interact with your application and its data. It requires authentication to ensure only authorized clients can consume your APIs. Scalekit provides a way to add OAuth 2.0-based client credentials authentication to your API endpoints. -In should here's how it would work: +Here's how it works:-User -> API Client: 4. Saves the API credetials +User -> API Client: 4. Saves the API credentials
74-232:⚠️ Potential issue | 🟠 MajorAdd Go/Java examples and use the standard tech‑stack tab values.
Step 2 only shows cURL + Python, and
value="curl"doesn’t match the required tech‑stack keys. Please add Node.js/Go/Java examples (keep cURL as optional) and usenode,python,go,javavalues.As per coding guidelines: “Include code examples in all 4 languages (Node.js, Python, Go, Java) within Steps components” and “Use consistent Tab labels for multi-language examples: 'Node.js', 'Python', 'Go', 'Java' with TabItem values 'node', 'python'/'py', 'go'/'golang', 'java'.”
🤖 Fix all issues with AI agents
In `@src/content/docs/authenticate/m2m/api-auth-quickstart.mdx`:
- Around line 393-418: The JSON sample contains a realistic-looking secret in
the "plain_secret" field that triggered secret scanning; replace that value with
a clearly fake placeholder (e.g., "PLAINTEXT_SECRET_PLACEHOLDER") and scan the
rest of this MDX file for any other realistic-looking tokens (e.g.,
secret_suffix, client_id, sks_* values) and replace them with generic
placeholders to avoid accidental reuse or scanning alerts; update the sample
JSON block shown in api-auth-quickstart.mdx and any other sample blocks in the
same file to use non-sensitive placeholders consistently.
- Around line 367-522: Fix the typo "or example" to "For example," and add Go
and Java TabItem examples alongside the existing curl, node, and python TabItem
blocks (use unique identifiers like Tabs(syncKey="tech-stack") and TabItem
value="go"/"java"); ensure the Tabs component is indented with 3 spaces inside
its parent Steps, each TabItem is at the same indentation level as its Tabs
parent, and code blocks inside each TabItem are properly indented to match the
other examples so the four-language requirement (Node.js, Python, Go, Java) and
indentation rules are satisfied.
In `@src/content/docs/authenticate/m2m/api-keys.mdx`:
- Around line 551-634: Update the three language examples to include explicit
success and error handling around the list calls (handle promise
rejection/exception and check returned error values) and replace redundant
comments with intent-focused ones; specifically wrap scalekit.token.listTokens
(JS), scalekit_client.tokens.list_tokens (Python), and
scalekitClient.Token().ListTokens (Go) calls with try/catch / if err / exception
handling and log or surface errors, check for nil/empty responses before
iterating (response, response[0], response.Tokens), and change comments to
explain why pagination or filtering is used (e.g., "iterate pages to fetch all
tokens" or "filter to tokens owned by a specific user") instead of restating the
code.
- Around line 21-23: Update the opening paragraph to fix grammar and
consistency: change "Scalekit API keys gives you" to "Scalekit API keys give
you", hyphenate "organization- or user-level", use consistent lowercase "API
keys" and hyphenate "client-side", and rework the second sentence to read
something like "Unlike JWT-based M2M authentication, API keys do not carry
embedded claims and cannot be validated on the client side; they must be
validated via Scalekit APIs, which then provide claims after server-side
validation." Ensure these edits are applied to the paragraph containing the
phrases "Scalekit API keys", "JWT-based M2M authentication", "client side", and
"API Keys can be validated via APIs with Scalekit".
- Around line 725-875: Add the required security comment string "// Security:
ALWAYS verify requests are from Scalekit before processing" immediately adjacent
to the token validation call in each example: in the Express middleware function
authenticateToken (where scalekit.token.validateToken is called), in the Flask
decorator authenticate_token (where scalekit_client.tokens.validate_token is
called), in the Gin handler AuthenticateToken (around
scalekitClient.Token().ValidateToken), and in the Spring Boot filter
TokenAuthFilter.doFilterInternal (around scalekitClient.tokens().validate);
place the comment right above or on the same line as the validation call so it
is clearly associated with the security check.
- Around line 1-6: Update the MDX frontmatter to add tableOfContents: true and
change the sidebar label to sentence case; specifically, in the existing
frontmatter where title: "API keys", description, sidebar: label: "Add API
Keys", and tags are defined, insert tableOfContents: true and change sidebar:
label to "Add API keys" so the page renders a TOC and the sidebar uses sentence
case.
🧹 Nitpick comments (1)
src/configs/redirects.config.ts (1)
258-260: Avoid a redirect chain for/m2m/scopes.
/m2m/scopescurrently hops through/guides/m2m/scopes/before reaching the new destination. Point it directly to the final URL to reduce one redirect.♻️ Suggested change
- '/m2m/scopes': '/guides/m2m/scopes/', + '/m2m/scopes': '/authenticate/m2m/api-auth-quickstart/', '/guides/m2m/scopes/': '/authenticate/m2m/api-auth-quickstart/',
📜 Review details
Configuration used: Repository UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (6)
src/configs/redirects.config.tssrc/configs/sidebar.config.tssrc/content/docs/authenticate/m2m/api-auth-quickstart.mdxsrc/content/docs/authenticate/m2m/api-keys.mdxsrc/content/docs/guides/m2m/api-auth-m2m-clients.mdxsrc/content/docs/guides/m2m/scopes.mdx
💤 Files with no reviewable changes (2)
- src/content/docs/guides/m2m/api-auth-m2m-clients.mdx
- src/content/docs/guides/m2m/scopes.mdx
🚧 Files skipped from review as they are similar to previous changes (1)
- src/configs/sidebar.config.ts
🧰 Additional context used
📓 Path-based instructions (7)
**/*.{js,ts,py,go,java,tsx,jsx}
📄 CodeRabbit inference engine (CLAUDE.md)
SDK variable names must follow language-specific conventions: Node.js uses
scalekit, Python usesscalekit_client, Go usesscalekitClient, Java usesscalekitClient
Files:
src/configs/redirects.config.ts
**/*.{js,ts,tsx,jsx,py,java,cs,go,cpp,c,rb,php,swift,kt,scala,rs,m,mm,groovy,gradle,xml,json}
📄 CodeRabbit inference engine (.cursor/rules/comment-standards.mdc)
Comments should not duplicate the code - avoid comments that simply restate what the code does; comments should add value beyond what's obvious from reading the code
Files:
src/configs/redirects.config.ts
**/*.{js,ts,tsx,jsx,py,java,cs,go,cpp,c,rb,php,swift,kt,scala,rs,m,mm,groovy}
📄 CodeRabbit inference engine (.cursor/rules/comment-standards.mdc)
**/*.{js,ts,tsx,jsx,py,java,cs,go,cpp,c,rb,php,swift,kt,scala,rs,m,mm,groovy}: Good comments do not excuse unclear code - refactor the code to be self-explanatory instead of using comments to explain poorly written code; use better variable names, function names, and code structure
Comments should dispel confusion, not cause it - ensure comments clarify rather than obscure the code's purpose; avoid cryptic or joke comments
Explain unidiomatic code in comments - comment on code that might seem unnecessary or redundant and document why you chose a specific pattern over more common alternatives, especially when it deviates from team conventions
Provide links to the original source of copied code - always attribute code copied from external sources with URLs to Stack Overflow answers, GitHub repositories, or documentation
Include links to external references where helpful - reference standards, RFCs, and official documentation; link to relevant specifications when implementing protocols
Add comments when fixing bugs - document bug fixes with context about the issue, reference issue trackers and bug reports, and explain workarounds and their limitations
Use comments to mark incomplete implementations - use standard formats for TODO, FIXME, and NOTE comments with context about what needs to be done and reference issue trackers when possible
Always document public APIs with function/class comments - explain the purpose, parameters, return values, and exceptions; include usage examples for complex functions
Include file headers with copyright information, license, and authorship - provide a brief description of the file's purpose and document dependencies and requirements
Files:
src/configs/redirects.config.ts
**/*.{js,ts,tsx,jsx}
📄 CodeRabbit inference engine (.cursor/rules/comment-standards.mdc)
Use JSDoc standards for all function, class, and complex logic comments in JavaScript/TypeScript - include parameter descriptions (
@param), return values (@returns), types (@type), and descriptions; document exceptions and edge cases
Files:
src/configs/redirects.config.ts
**/*.mdx
📄 CodeRabbit inference engine (.cursorrules)
**/*.mdx: Use clear, descriptive titles that explain the purpose of the document
Include comprehensive descriptions in frontmatter metadata
Organize content with logical heading hierarchy (H2, H3, H4)
Use tableOfContents property in frontmatter when content has multiple sections
Set appropriate sidebar labels for navigation in frontmatter
Use direct instruction writing style with phrases like 'This guide shows you how to...' and 'Create an authorization URL to...'
Use second person perspective ('your application', 'you receive', 'you must') in documentation
Keep sentences concise, aiming for under 25 words per sentence
Explain the 'why' in documentation with phrases like 'This prevents CSRF attacks by...' or 'Use this to validate that...'
Use action verbs in section headings: 'Store session tokens securely', 'Validate the state parameter', 'Exchange authorization code for tokens'
Use present tense for descriptions: 'Scalekit handles the complex authentication flow', 'The SDK provides methods to refresh tokens'
Use future tense for results: 'This will redirect users to...', 'You'll receive a JWT containing...', 'Scalekit returns an authorization code'
Use transition phrases between sections: 'After the user authenticates...', 'Once the state is validated...', 'Let's take a look at how to...'
Write 1-3 opening paragraphs that explain what users will accomplish, provide context about when/why, preview key concepts, and use direct instructional language
Begin introduction sections with a clear statement of what the guide covers and explain the problem being solved
Use collapsible sections in introduction for sequence diagrams, video demonstrations, data models, and JSON examples with appropriate icons
Use numbered format within Steps component:1. ## Titlewith all step content indented with exactly 3 spaces
Use action-oriented headings in step-by-step guides within Steps components
Include code examples in all 4 languages (Node.js, Python, Go, Java) within Steps co...
Files:
src/content/docs/authenticate/m2m/api-auth-quickstart.mdxsrc/content/docs/authenticate/m2m/api-keys.mdx
**/*.{md,mdx}
📄 CodeRabbit inference engine (CLAUDE.md)
**/*.{md,mdx}: All code examples must include implementations in all 4 languages: Node.js, Python, Go, and Java
Include security comments in code examples explaining security threats and implications
Code examples must demonstrate both success and error paths
Frontmatter must include: title (≤60 characters), description (≤160 characters), sidebar label, order number, and tags array
Use second person ('you', 'your application') for writing voice in documentation
Use present tense for descriptions and imperative mood for instructions in documentation
**/*.{md,mdx}: Use sentence case for all titles and headings in MD/MDX documentation
Keep page titles short and descriptive (3–7 words when possible) in MD/MDX documentation
Use outcome-focused headings that describe results, not categories (e.g., 'Run a script' not 'Scripts')
Avoid gerunds in headings when an imperative works - prefer 'Configure proxies' over 'Configuring proxies'
Keep sidebar labels concise (1–3 words), use sentence case, and focus on outcomes or objects
Use sentence case in sidebar labels without punctuation
Set frontmatter title in sentence case with a clear outcome; description in one sentence (≤160 chars); sidebar.label as shorter form of title; enable tableOfContents on longer pages
Start documentation pages with a one-paragraph overview explaining what the page covers and when to use it
Present the primary use case (80% path) first in documentation, with edge cases later
Use numbered steps for task-focused sections in documentation, with each step beginning with a verb
Break up long documentation sections with subheadings every 3–6 paragraphs
Use asides for important notes, tips, cautions, and references in documentation
Provide runnable, minimal code examples that work as-is in documentation
Prefer CLI-first examples and show file layout when helpful in documentation
Label code blocks with titles for context (e.g., 'Terminal', 'main.ts') in documentation
Keep code block annotations brief and...
Files:
src/content/docs/authenticate/m2m/api-auth-quickstart.mdxsrc/content/docs/authenticate/m2m/api-keys.mdx
**/*.{yml,yaml,md,mdx}
📄 CodeRabbit inference engine (.cursor/rules/browsecentral-labels.mdc)
**/*.{yml,yaml,md,mdx}: BrowseCentral labels should be maximum 3-5 words - keep concise but add context when needed
BrowseCentral labels should be action-oriented - start with verbs when possible
BrowseCentral labels should be specific and clear - add context when simple labels are ambiguous
BrowseCentral labels should be outcome-focused - describe what users accomplish and the context
BrowseCentral labels should use 'Action + Object' pattern (e.g., 'Invite users', 'Restrict sign-up', 'Set up SCIM')
BrowseCentral labels should use feature names (e.g., 'Enterprise SSO', 'Passwordless quickstart')
BrowseCentral labels should describe task completion (e.g., 'Run migrations', 'Migrate auth', 'Merge identities')
BrowseCentral labels should include specific context when needed (e.g., 'Configure Scalekit MCP server', 'Validate incoming API requests')
BrowseCentral labels should use integration context when applicable (e.g., 'Build MCP auth with your existing auth system')
BrowseCentral labels should avoid instructional prefixes: 'How to', 'Guide to', 'Implement', 'Configure', 'Learn', 'Understand'
BrowseCentral labels should avoid verbose phrases: 'Step-by-step guide', 'Complete tutorial', 'Detailed documentation'
BrowseCentral labels should avoid weak verbs: 'Enable', 'Allow', 'Provide', 'Support'
Files:
src/content/docs/authenticate/m2m/api-auth-quickstart.mdxsrc/content/docs/authenticate/m2m/api-keys.mdx
🧠 Learnings (10)
📓 Common learnings
Learnt from: saif-at-scalekit
Repo: scalekit-inc/developer-docs PR: 424
File: public/api/scalekit.scalar.json:3451-3457
Timestamp: 2026-02-10T05:32:59.967Z
Learning: In scalekit-inc/developer-docs, the file public/api/scalekit.scalar.json is a generated OpenAPI artifact; reviewers should avoid direct edits. For inconsistencies (e.g., the /api/v1/permissions "type" query param description vs. enum), handle short-term via release/PR notes and track long-term fixes in the generator or source templates rather than modifying the generated JSON.
Learnt from: AkshayParihar33
Repo: scalekit-inc/developer-docs PR: 415
File: src/content/docs/authenticate/fsa/multiapp/native-app.mdx:72-179
Timestamp: 2026-02-02T05:55:51.251Z
Learning: In the `src/content/docs/authenticate/fsa/multiapp/` directory, the multi-app authentication documentation (native-app.mdx, single-page-app.mdx, web-app.mdx, overview.mdx) currently uses conceptual shell/curl examples instead of multi-language SDK code examples because the Scalekit SDKs have not yet been built/updated for multi-app functionality. Once the SDKs are ready, these files should be updated to include all 4 languages (Node.js, Python, Go, Java) using `<Tabs syncKey="tech-stack">`.
📚 Learning: 2026-01-13T12:46:55.260Z
Learnt from: CR
Repo: scalekit-inc/developer-docs PR: 0
File: .cursorrules:0-0
Timestamp: 2026-01-13T12:46:55.260Z
Learning: Applies to **/*.mdx : Use present tense for descriptions: 'Scalekit handles the complex authentication flow', 'The SDK provides methods to refresh tokens'
Applied to files:
src/content/docs/authenticate/m2m/api-auth-quickstart.mdxsrc/content/docs/authenticate/m2m/api-keys.mdx
📚 Learning: 2026-02-02T05:55:51.251Z
Learnt from: AkshayParihar33
Repo: scalekit-inc/developer-docs PR: 415
File: src/content/docs/authenticate/fsa/multiapp/native-app.mdx:72-179
Timestamp: 2026-02-02T05:55:51.251Z
Learning: In the `src/content/docs/authenticate/fsa/multiapp/` directory, the multi-app authentication documentation (native-app.mdx, single-page-app.mdx, web-app.mdx, overview.mdx) currently uses conceptual shell/curl examples instead of multi-language SDK code examples because the Scalekit SDKs have not yet been built/updated for multi-app functionality. Once the SDKs are ready, these files should be updated to include all 4 languages (Node.js, Python, Go, Java) using `<Tabs syncKey="tech-stack">`.
Applied to files:
src/content/docs/authenticate/m2m/api-auth-quickstart.mdxsrc/content/docs/authenticate/m2m/api-keys.mdx
📚 Learning: 2026-01-13T12:48:11.566Z
Learnt from: CR
Repo: scalekit-inc/developer-docs PR: 0
File: .cursor/rules/documentation-guide.mdc:0-0
Timestamp: 2026-01-13T12:48:11.566Z
Learning: Applies to **/*.mdx : Use Tabs/TabItem components for multi-language or multi-framework examples in MDX documentation
Applied to files:
src/content/docs/authenticate/m2m/api-auth-quickstart.mdx
📚 Learning: 2026-01-13T12:46:55.260Z
Learnt from: CR
Repo: scalekit-inc/developer-docs PR: 0
File: .cursorrules:0-0
Timestamp: 2026-01-13T12:46:55.260Z
Learning: Applies to **/*.mdx : Tabs components within Steps must be indented with 3 spaces, TabItem at same level as parent Tabs, code blocks properly indented within TabItem
Applied to files:
src/content/docs/authenticate/m2m/api-auth-quickstart.mdx
📚 Learning: 2026-01-30T18:18:50.883Z
Learnt from: AkshayParihar33
Repo: scalekit-inc/developer-docs PR: 415
File: src/content/docs/authenticate/fsa/multiapp/manage-apps.mdx:31-49
Timestamp: 2026-01-30T18:18:50.883Z
Learning: In all Scalekit documentation files (MDX), treat the terms 'Applications', 'Single Page Application (SPA)', 'Native Application', and 'Web Application' as proper nouns and preserve their capitalization in headings and body text. Ensure these terms remain capitalized even when used in sentence case or within prose.
Applied to files:
src/content/docs/authenticate/m2m/api-auth-quickstart.mdxsrc/content/docs/authenticate/m2m/api-keys.mdx
📚 Learning: 2026-02-04T12:47:16.544Z
Learnt from: saif-at-scalekit
Repo: scalekit-inc/developer-docs PR: 412
File: src/content/docs/dev-kit/tools/scalekit-dryrun.mdx:1-23
Timestamp: 2026-02-04T12:47:16.544Z
Learning: In scalekit-inc/developer-docs, the MDX frontmatter field order is required only when the sidebar configuration points to a directory (for auto-generation). If the sidebar.config.ts references a specific file path, the order field is not required. Apply this check to all MDX files under src/content/docs: if a file contributes to an auto-generated sidebar (directory path), ensure order is present; if it’s linked to a concrete file, order can be omitted. Use sidebar.config.ts to determine whether a given MDX file falls under directory-based vs file-specific sidebar references.
Applied to files:
src/content/docs/authenticate/m2m/api-auth-quickstart.mdxsrc/content/docs/authenticate/m2m/api-keys.mdx
📚 Learning: 2026-02-10T05:32:59.967Z
Learnt from: saif-at-scalekit
Repo: scalekit-inc/developer-docs PR: 424
File: public/api/scalekit.scalar.json:3451-3457
Timestamp: 2026-02-10T05:32:59.967Z
Learning: In scalekit-inc/developer-docs, the file public/api/scalekit.scalar.json is a generated OpenAPI artifact; reviewers should avoid direct edits. For inconsistencies (e.g., the /api/v1/permissions "type" query param description vs. enum), handle short-term via release/PR notes and track long-term fixes in the generator or source templates rather than modifying the generated JSON.
Applied to files:
src/content/docs/authenticate/m2m/api-keys.mdx
📚 Learning: 2026-01-13T12:46:55.260Z
Learnt from: CR
Repo: scalekit-inc/developer-docs PR: 0
File: .cursorrules:0-0
Timestamp: 2026-01-13T12:46:55.260Z
Learning: Applies to **/*.mdx : Include context comments explaining what's happening in code: '// Extract encrypted tokens from request cookies', '// Decrypt the access token before validation'
Applied to files:
src/content/docs/authenticate/m2m/api-keys.mdx
📚 Learning: 2026-01-13T12:46:55.260Z
Learnt from: CR
Repo: scalekit-inc/developer-docs PR: 0
File: .cursorrules:0-0
Timestamp: 2026-01-13T12:46:55.260Z
Learning: Applies to **/*.mdx : Use action verbs in section headings: 'Store session tokens securely', 'Validate the state parameter', 'Exchange authorization code for tokens'
Applied to files:
src/content/docs/authenticate/m2m/api-keys.mdx
🪛 Gitleaks (8.30.0)
src/content/docs/authenticate/m2m/api-auth-quickstart.mdx
[high] 417-417: Detected a Generic API Key, potentially exposing access to various services and sensitive operations.
(generic-api-key)
🪛 LanguageTool
src/content/docs/authenticate/m2m/api-auth-quickstart.mdx
[grammar] ~28-~28: Use a hyphen to join words.
Context: ... Scalekit provides a way to add OAuth2.0 based client credentials authentication ...
(QB_NEW_EN_HYPHEN)
✏️ Tip: You can disable this entire section by setting review_details to false in your review settings.
| 5. ## Register API client's scopes <Badge text="Optional" /> | ||
|
|
||
| Scopes are embedded in the access token and validated server-side using the Scalekit SDK. This ensures that API clients only access resources they're authorized for, adding an extra layer of security. | ||
|
|
||
| or example, you might create an API client for a customer's deployment service with scopes like `deploy:applications` and `read:deployments`. | ||
|
|
||
| <Tabs syncKey="tech-stack"> | ||
| <TabItem value="curl" label="cURL"> | ||
|
|
||
| ```bash title="Register an API client with specific scopes" wrap | ||
| curl -L 'https://<SCALEKIT_ENVIRONMENT_URL>/api/v1/organizations/<ORGANIZATION_ID>/clients' \ | ||
| -H 'Content-Type: application/json' \ | ||
| -H 'Authorization: Bearer <SCALEKIT_ACCESS_TOKEN>' \ | ||
| -d '{ | ||
| "name": "GitHub Actions Deployment Service", | ||
| "description": "Service account for GitHub Actions to deploy applications to production", | ||
| "scopes": [ | ||
| "deploy:applications", | ||
| "read:deployments" | ||
| ], | ||
| "expiry": 3600 | ||
| }' | ||
| ``` | ||
| <details> | ||
| <summary>Sample response</summary> | ||
|
|
||
| ```json title="Sample response" showLineNumbers=false | ||
| { | ||
| "client": { | ||
| "client_id": "m2morg_68315758685323697", | ||
| "secrets": [ | ||
| { | ||
| "id": "sks_68315758802764209", | ||
| "create_time": "2025-04-16T06:56:05.360Z", | ||
| "update_time": "2025-04-16T06:56:05.367190455Z", | ||
| "secret_suffix": "UZ0X", | ||
| "status": "ACTIVE", | ||
| "last_used_time": "2025-04-16T06:56:05.360Z" | ||
| } | ||
| ], | ||
| "name": "GitHub Actions Deployment Service", | ||
| "description": "Service account for GitHub Actions to deploy applications to production", | ||
| "organization_id": "org_59615193906282635", | ||
| "create_time": "2025-04-16T06:56:05.290Z", | ||
| "update_time": "2025-04-16T06:56:05.292145150Z", | ||
| "scopes": [ | ||
| "deploy:applications", | ||
| "read:deployments" | ||
| ] | ||
| }, | ||
| "plain_secret": "test_ly8G57h0ErRJSObJI6dShkoaq6bigo11Dxcfa6reKG1kKNVbqBKW4H5Ctmb5UZ0X" | ||
| } | ||
| ``` | ||
| </details> | ||
| </TabItem> | ||
| <TabItem value="node" label="Node.js"> | ||
|
|
||
| ```javascript title="Register an API client with specific scopes" | ||
| // Use case: Your customer requests API access for their deployment automation. | ||
| // You register an API client app with the appropriate scopes. | ||
| import { ScalekitClient } from '@scalekit-sdk/node'; | ||
|
|
||
| // Initialize Scalekit client (see installation guide for setup) | ||
| const scalekit = new ScalekitClient( | ||
| process.env.SCALEKIT_ENVIRONMENT_URL, | ||
| process.env.SCALEKIT_CLIENT_ID, | ||
| process.env.SCALEKIT_CLIENT_SECRET | ||
| ); | ||
|
|
||
| async function createAPIClient() { | ||
| try { | ||
| // Define API client details with scopes your customer's app needs | ||
| const clientDetails = { | ||
| name: 'GitHub Actions Deployment Service', | ||
| description: 'Service account for GitHub Actions to deploy applications to production', | ||
| scopes: ['deploy:applications', 'read:deployments'], | ||
| expiry: 3600, // Token expiry in seconds | ||
| }; | ||
|
|
||
| // API call to register the client | ||
| const response = await scalekit.m2m.createClient({ | ||
| organizationId: process.env.SCALEKIT_ORGANIZATION_ID, | ||
| client: clientDetails, | ||
| }); | ||
|
|
||
| // Response contains client details and the plain_secret (only returned once) | ||
| const clientId = response.client.client_id; | ||
| const plainSecret = response.plain_secret; | ||
|
|
||
| // Provide these credentials to your customer securely | ||
| console.log('Created API client:', clientId); | ||
| } catch (error) { | ||
| console.error('Error creating API client:', error); | ||
| } | ||
| } | ||
|
|
||
| createAPIClient(); | ||
| ``` | ||
|
|
||
| </TabItem> | ||
| <TabItem value="python" label="Python"> | ||
|
|
||
| ```python title="Register an API client with specific scopes" | ||
| # Use case: Your customer requests API access for their deployment automation. | ||
| # You register an API client app with the appropriate scopes. | ||
| import os | ||
| from scalekit import ScalekitClient | ||
|
|
||
| # Initialize Scalekit client (see installation guide for setup) | ||
| scalekit_client = ScalekitClient( | ||
| env_url=os.getenv("SCALEKIT_ENVIRONMENT_URL"), | ||
| client_id=os.getenv("SCALEKIT_CLIENT_ID"), | ||
| client_secret=os.getenv("SCALEKIT_CLIENT_SECRET") | ||
| ) | ||
|
|
||
| try: | ||
| # Define API client details with scopes your customer's app needs | ||
| from scalekit.v1.clients.clients_pb2 import OrganizationClient | ||
|
|
||
| client_details = OrganizationClient( | ||
| name="GitHub Actions Deployment Service", | ||
| description="Service account for GitHub Actions to deploy applications to production", | ||
| scopes=["deploy:applications", "read:deployments"], | ||
| expiry=3600 # Token expiry in seconds | ||
| ) | ||
|
|
||
| # API call to register the client | ||
| response = scalekit_client.m2m_client.create_organization_client( | ||
| organization_id=os.getenv("SCALEKIT_ORGANIZATION_ID"), | ||
| m2m_client=client_details | ||
| ) | ||
|
|
||
| # Response contains client details and the plain_secret (only returned once) | ||
| client_id = response.client.client_id | ||
| plain_secret = response.plain_secret | ||
|
|
||
| # Provide these credentials to your customer securely | ||
| print("Created API client:", client_id) | ||
|
|
||
| except Exception as e: | ||
| print("Error creating API client:", e) | ||
| ``` | ||
|
|
||
| </TabItem> | ||
| </Tabs> | ||
|
|
||
| The API returns a JSON object with two key parts: | ||
| - `client.client_id` - The client identifier | ||
| - `plain_secret` - The client secret (only returned once, never stored by Scalekit) | ||
|
|
||
| Provide both values to your customer securely. Your customer will use these credentials in their application to authenticate with your API. The `plain_secret` is never shown again after creation. | ||
|
|
||
| <Aside type="tip" title="Additional parameters"> | ||
| You can also include `custom_claims` (key-value metadata) and `audience` (target API endpoints) when registering API clients. See the [quickstart guide](/authenticate/m2m/api-auth-quickstart) for examples. | ||
| </Aside> | ||
|
|
There was a problem hiding this comment.
Fix typo and add Go/Java tabs for the scopes section.
This step has a typo (“or example”) and only cURL/Node/Python. Add Go/Java to meet the 4‑language requirement, and ensure Tabs/TabItem indentation stays consistent within <Steps>.
✏️ Typo fix
- or example, you might create an API client for a customer's deployment service with scopes like `deploy:applications` and `read:deployments`.
+ For example, you might create an API client for a customer's deployment service with scopes like `deploy:applications` and `read:deployments`.As per coding guidelines: “Include code examples in all 4 languages (Node.js, Python, Go, Java) within Steps components.” Based on learnings: “Tabs components within Steps must be indented with 3 spaces, TabItem at same level as parent Tabs, code blocks properly indented within TabItem.”
🧰 Tools
🪛 Gitleaks (8.30.0)
[high] 417-417: Detected a Generic API Key, potentially exposing access to various services and sensitive operations.
(generic-api-key)
🤖 Prompt for AI Agents
In `@src/content/docs/authenticate/m2m/api-auth-quickstart.mdx` around lines 367 -
522, Fix the typo "or example" to "For example," and add Go and Java TabItem
examples alongside the existing curl, node, and python TabItem blocks (use
unique identifiers like Tabs(syncKey="tech-stack") and TabItem
value="go"/"java"); ensure the Tabs component is indented with 3 spaces inside
its parent Steps, each TabItem is at the same indentation level as its Tabs
parent, and code blocks inside each TabItem are properly indented to match the
other examples so the four-language requirement (Node.js, Python, Go, Java) and
indentation rules are satisfied.
| ```json title="Sample response" showLineNumbers=false | ||
| { | ||
| "client": { | ||
| "client_id": "m2morg_68315758685323697", | ||
| "secrets": [ | ||
| { | ||
| "id": "sks_68315758802764209", | ||
| "create_time": "2025-04-16T06:56:05.360Z", | ||
| "update_time": "2025-04-16T06:56:05.367190455Z", | ||
| "secret_suffix": "UZ0X", | ||
| "status": "ACTIVE", | ||
| "last_used_time": "2025-04-16T06:56:05.360Z" | ||
| } | ||
| ], | ||
| "name": "GitHub Actions Deployment Service", | ||
| "description": "Service account for GitHub Actions to deploy applications to production", | ||
| "organization_id": "org_59615193906282635", | ||
| "create_time": "2025-04-16T06:56:05.290Z", | ||
| "update_time": "2025-04-16T06:56:05.292145150Z", | ||
| "scopes": [ | ||
| "deploy:applications", | ||
| "read:deployments" | ||
| ] | ||
| }, | ||
| "plain_secret": "test_ly8G57h0ErRJSObJI6dShkoaq6bigo11Dxcfa6reKG1kKNVbqBKW4H5Ctmb5UZ0X" | ||
| } |
There was a problem hiding this comment.
Replace sample secrets with placeholders.
The sample plain_secret value looks like a real token and triggered secret scanning. Use a placeholder (and update other samples in this file) to avoid accidental reuse.
🔒 Suggested redaction
- "plain_secret": "test_ly8G57h0ErRJSObJI6dShkoaq6bigo11Dxcfa6reKG1kKNVbqBKW4H5Ctmb5UZ0X"
+ "plain_secret": "<PLAIN_SECRET>"🧰 Tools
🪛 Gitleaks (8.30.0)
[high] 417-417: Detected a Generic API Key, potentially exposing access to various services and sensitive operations.
(generic-api-key)
🤖 Prompt for AI Agents
In `@src/content/docs/authenticate/m2m/api-auth-quickstart.mdx` around lines 393 -
418, The JSON sample contains a realistic-looking secret in the "plain_secret"
field that triggered secret scanning; replace that value with a clearly fake
placeholder (e.g., "PLAINTEXT_SECRET_PLACEHOLDER") and scan the rest of this MDX
file for any other realistic-looking tokens (e.g., secret_suffix, client_id,
sks_* values) and replace them with generic placeholders to avoid accidental
reuse or scanning alerts; update the sample JSON block shown in
api-auth-quickstart.mdx and any other sample blocks in the same file to use
non-sensitive placeholders consistently.
| --- | ||
| title: API keys | ||
| description: "Issue long-lived, revocable API keys scoped to organizations and users for programmatic access to your APIs" | ||
| sidebar: | ||
| label: "Add API Keys" | ||
| tags: [api-tokens, api-keys, m2m, authentication, bearer-tokens] |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
rg -n "authenticate/m2m" src/configs/sidebar.config.tsRepository: scalekit-inc/developer-docs
Length of output: 165
🏁 Script executed:
sed -n '60,80p' src/configs/sidebar.config.tsRepository: scalekit-inc/developer-docs
Length of output: 857
Add tableOfContents and fix sidebar label to sentence case.
The page has multiple sections and requires tableOfContents: true in frontmatter. The sidebar label should use sentence case: "Add API keys" (not "Add API Keys").
✏️ Suggested frontmatter update
sidebar:
- label: "Add API Keys"
+ label: "Add API keys"
+tableOfContents: true🤖 Prompt for AI Agents
In `@src/content/docs/authenticate/m2m/api-keys.mdx` around lines 1 - 6, Update
the MDX frontmatter to add tableOfContents: true and change the sidebar label to
sentence case; specifically, in the existing frontmatter where title: "API
keys", description, sidebar: label: "Add API Keys", and tags are defined, insert
tableOfContents: true and change sidebar: label to "Add API keys" so the page
renders a TOC and the sidebar uses sentence case.
| When your customers need to integrate with your APIs — whether for CI/CD pipelines, partner integrations, or internal tooling — they need a straightforward way to authenticate. Scalekit API keys gives you long-lived, revocable bearer credentials that can be issued to your customers for Organizational or User Level access to your APIs. | ||
|
|
||
| Unlike [JWT-based M2M authentication](/authenticate/m2m/api-auth-quickstart/), API keys do not carry embedded claims and cannot be validated on the client side. The API Keys can be validated via APIs with Scalekit and after server-side validation, the claims are sent when a valid API Key is presented. Revocation of API keys takes effect immediately with no expiry windows or propagation delays. Each key is scoped to an organization and optionally to a specific user, making it easy to build personal access tokens, per-user rate limiting, and audit trails. |
There was a problem hiding this comment.
Tighten grammar and consistency in the opening paragraph.
A few fixes improve readability and consistency (“API keys give you…”, “organization- or user-level”, “API keys”, and “client-side”).
✏️ Suggested edits
-Scalekit API keys gives you long-lived, revocable bearer credentials that can be issued to your customers for Organizational or User Level access to your APIs.
+Scalekit API keys give you long-lived, revocable bearer credentials that can be issued to your customers for organization- or user-level access to your APIs.
-Unlike [JWT-based M2M authentication](/authenticate/m2m/api-auth-quickstart/), API keys do not carry embedded claims and cannot be validated on the client side. The API Keys can be validated via APIs with Scalekit and after server-side validation, the claims are sent when a valid API Key is presented.
+Unlike [JWT-based M2M authentication](/authenticate/m2m/api-auth-quickstart/), API keys do not carry embedded claims and cannot be validated on the client-side. API keys can be validated via APIs with Scalekit and after server-side validation, the claims are sent when a valid API key is presented.🤖 Prompt for AI Agents
In `@src/content/docs/authenticate/m2m/api-keys.mdx` around lines 21 - 23, Update
the opening paragraph to fix grammar and consistency: change "Scalekit API keys
gives you" to "Scalekit API keys give you", hyphenate "organization- or
user-level", use consistent lowercase "API keys" and hyphenate "client-side",
and rework the second sentence to read something like "Unlike JWT-based M2M
authentication, API keys do not carry embedded claims and cannot be validated on
the client side; they must be validated via Scalekit APIs, which then provide
claims after server-side validation." Ensure these edits are applied to the
paragraph containing the phrases "Scalekit API keys", "JWT-based M2M
authentication", "client side", and "API Keys can be validated via APIs with
Scalekit".
| ```javascript title="Express.js" | ||
| import { ScalekitValidateTokenFailureException } from '@scalekit-sdk/node'; | ||
|
|
||
| async function authenticateToken(req, res, next) { | ||
| const authHeader = req.headers['authorization']; | ||
| const token = authHeader && authHeader.split(' ')[1]; | ||
|
|
||
| if (!token) { | ||
| // Reject requests without credentials to prevent unauthorized access | ||
| return res.status(401).json({ error: 'Missing authorization token' }); | ||
| } | ||
|
|
||
| try { | ||
| // Server-side validation — Scalekit checks token status in real time | ||
| const result = await scalekit.token.validateToken(token); | ||
| // Attach token context to the request for downstream handlers | ||
| req.tokenInfo = result.tokenInfo; | ||
| next(); | ||
| } catch (error) { | ||
| if (error instanceof ScalekitValidateTokenFailureException) { | ||
| // Revoked, expired, or malformed tokens are rejected immediately | ||
| return res.status(401).json({ error: 'Invalid or expired token' }); | ||
| } | ||
| throw error; | ||
| } | ||
| } | ||
|
|
||
| // Apply to protected routes | ||
| app.get('/api/resources', authenticateToken, (req, res) => { | ||
| const orgId = req.tokenInfo.organizationId; | ||
| // Serve resources scoped to this organization | ||
| }); | ||
| ``` | ||
|
|
||
| </TabItem> | ||
| <TabItem value="python" label="Python"> | ||
|
|
||
| ```python title="Flask" | ||
| from functools import wraps | ||
| from flask import request, jsonify, g | ||
| from scalekit import ScalekitValidateTokenFailureException | ||
|
|
||
| def authenticate_token(f): | ||
| @wraps(f) | ||
| def decorated(*args, **kwargs): | ||
| auth_header = request.headers.get("Authorization", "") | ||
| if not auth_header.startswith("Bearer "): | ||
| # Reject requests without credentials to prevent unauthorized access | ||
| return jsonify({"error": "Missing authorization token"}), 401 | ||
|
|
||
| token = auth_header.split(" ")[1] | ||
|
|
||
| try: | ||
| # Server-side validation — Scalekit checks token status in real time | ||
| result = scalekit_client.tokens.validate_token(token=token) | ||
| # Attach token context for downstream handlers | ||
| g.token_info = result[0].token_info | ||
| except ScalekitValidateTokenFailureException: | ||
| # Revoked, expired, or malformed tokens are rejected immediately | ||
| return jsonify({"error": "Invalid or expired token"}), 401 | ||
|
|
||
| return f(*args, **kwargs) | ||
| return decorated | ||
|
|
||
| # Apply to protected routes | ||
| @app.route("/api/resources") | ||
| @authenticate_token | ||
| def get_resources(): | ||
| org_id = g.token_info.organization_id | ||
| # Serve resources scoped to this organization | ||
| ``` | ||
|
|
||
| </TabItem> | ||
| <TabItem value="go" label="Go"> | ||
|
|
||
| ```go title="Gin" | ||
| func AuthenticateToken(scalekitClient scalekit.Scalekit) gin.HandlerFunc { | ||
| return func(c *gin.Context) { | ||
| authHeader := c.GetHeader("Authorization") | ||
| if !strings.HasPrefix(authHeader, "Bearer ") { | ||
| // Reject requests without credentials to prevent unauthorized access | ||
| c.JSON(401, gin.H{"error": "Missing authorization token"}) | ||
| c.Abort() | ||
| return | ||
| } | ||
|
|
||
| token := strings.TrimPrefix(authHeader, "Bearer ") | ||
|
|
||
| // Server-side validation — Scalekit checks token status in real time | ||
| result, err := scalekitClient.Token().ValidateToken(c.Request.Context(), token) | ||
| if errors.Is(err, scalekit.ErrTokenValidationFailed) { | ||
| // Revoked, expired, or malformed tokens are rejected immediately | ||
| c.JSON(401, gin.H{"error": "Invalid or expired token"}) | ||
| c.Abort() | ||
| return | ||
| } | ||
|
|
||
| // Attach token context for downstream handlers | ||
| c.Set("tokenInfo", result.TokenInfo) | ||
| c.Next() | ||
| } | ||
| } | ||
|
|
||
| // Apply to protected routes | ||
| r.GET("/api/resources", AuthenticateToken(scalekitClient), func(c *gin.Context) { | ||
| tokenInfo := c.MustGet("tokenInfo").(*scalekit.TokenInfo) | ||
| orgId := tokenInfo.OrganizationId | ||
| // Serve resources scoped to this organization | ||
| }) | ||
| ``` | ||
|
|
||
| </TabItem> | ||
| <TabItem value="java" label="Java"> | ||
|
|
||
| ```java title="Spring Boot" | ||
| import com.scalekit.exceptions.TokenInvalidException; | ||
|
|
||
| @Component | ||
| public class TokenAuthFilter extends OncePerRequestFilter { | ||
| private final ScalekitClient scalekitClient; | ||
|
|
||
| public TokenAuthFilter(ScalekitClient scalekitClient) { | ||
| this.scalekitClient = scalekitClient; | ||
| } | ||
|
|
||
| @Override | ||
| protected void doFilterInternal( | ||
| HttpServletRequest request, | ||
| HttpServletResponse response, | ||
| FilterChain filterChain | ||
| ) throws ServletException, IOException { | ||
| String authHeader = request.getHeader("Authorization"); | ||
| if (authHeader == null || !authHeader.startsWith("Bearer ")) { | ||
| // Reject requests without credentials to prevent unauthorized access | ||
| response.sendError(401, "Missing authorization token"); | ||
| return; | ||
| } | ||
|
|
||
| String token = authHeader.substring(7); | ||
|
|
||
| try { | ||
| // Server-side validation — Scalekit checks token status in real time | ||
| ValidateTokenResponse result = scalekitClient.tokens().validate(token); | ||
| // Attach token context for downstream handlers | ||
| request.setAttribute("tokenInfo", result.getTokenInfo()); | ||
| filterChain.doFilter(request, response); | ||
| } catch (TokenInvalidException e) { | ||
| // Revoked, expired, or malformed tokens are rejected immediately | ||
| response.sendError(401, "Invalid or expired token"); | ||
| } | ||
| } |
There was a problem hiding this comment.
Add the required security comment pattern in middleware examples.
Security-related code must include the standard comment string. Please add it in each language example near token validation.
✏️ Example (Node.js)
try {
+ // Security: ALWAYS verify requests are from Scalekit before processing
// Server-side validation — Scalekit checks token status in real time
const result = await scalekit.token.validateToken(token);As per coding guidelines: “Always include security comments in security-related code with pattern: '// Security: ALWAYS verify requests are from Scalekit before processing'.”
🤖 Prompt for AI Agents
In `@src/content/docs/authenticate/m2m/api-keys.mdx` around lines 725 - 875, Add
the required security comment string "// Security: ALWAYS verify requests are
from Scalekit before processing" immediately adjacent to the token validation
call in each example: in the Express middleware function authenticateToken
(where scalekit.token.validateToken is called), in the Flask decorator
authenticate_token (where scalekit_client.tokens.validate_token is called), in
the Gin handler AuthenticateToken (around scalekitClient.Token().ValidateToken),
and in the Spring Boot filter TokenAuthFilter.doFilterInternal (around
scalekitClient.tokens().validate); place the comment right above or on the same
line as the validation call so it is clearly associated with the security check.
…ters for Go optional proto fields, add missing Token import in Java middleware
… error handling to list/invalidate examples across all languages
There was a problem hiding this comment.
Actionable comments posted: 8
📜 Review details
Configuration used: Repository UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (1)
src/content/docs/authenticate/m2m/api-keys.mdx
🧰 Additional context used
📓 Path-based instructions (3)
**/*.mdx
📄 CodeRabbit inference engine (.cursorrules)
**/*.mdx: Use clear, descriptive titles that explain the purpose of the document
Include comprehensive descriptions in frontmatter metadata
Organize content with logical heading hierarchy (H2, H3, H4)
Use tableOfContents property in frontmatter when content has multiple sections
Set appropriate sidebar labels for navigation in frontmatter
Use direct instruction writing style with phrases like 'This guide shows you how to...' and 'Create an authorization URL to...'
Use second person perspective ('your application', 'you receive', 'you must') in documentation
Keep sentences concise, aiming for under 25 words per sentence
Explain the 'why' in documentation with phrases like 'This prevents CSRF attacks by...' or 'Use this to validate that...'
Use action verbs in section headings: 'Store session tokens securely', 'Validate the state parameter', 'Exchange authorization code for tokens'
Use present tense for descriptions: 'Scalekit handles the complex authentication flow', 'The SDK provides methods to refresh tokens'
Use future tense for results: 'This will redirect users to...', 'You'll receive a JWT containing...', 'Scalekit returns an authorization code'
Use transition phrases between sections: 'After the user authenticates...', 'Once the state is validated...', 'Let's take a look at how to...'
Write 1-3 opening paragraphs that explain what users will accomplish, provide context about when/why, preview key concepts, and use direct instructional language
Begin introduction sections with a clear statement of what the guide covers and explain the problem being solved
Use collapsible sections in introduction for sequence diagrams, video demonstrations, data models, and JSON examples with appropriate icons
Use numbered format within Steps component:1. ## Titlewith all step content indented with exactly 3 spaces
Use action-oriented headings in step-by-step guides within Steps components
Include code examples in all 4 languages (Node.js, Python, Go, Java) within Steps co...
Files:
src/content/docs/authenticate/m2m/api-keys.mdx
**/*.{yml,yaml,md,mdx}
📄 CodeRabbit inference engine (.cursor/rules/browsecentral-labels.mdc)
**/*.{yml,yaml,md,mdx}: BrowseCentral labels should be maximum 3-5 words - keep concise but add context when needed
BrowseCentral labels should be action-oriented - start with verbs when possible
BrowseCentral labels should be specific and clear - add context when simple labels are ambiguous
BrowseCentral labels should be outcome-focused - describe what users accomplish and the context
BrowseCentral labels should use 'Action + Object' pattern (e.g., 'Invite users', 'Restrict sign-up', 'Set up SCIM')
BrowseCentral labels should use feature names (e.g., 'Enterprise SSO', 'Passwordless quickstart')
BrowseCentral labels should describe task completion (e.g., 'Run migrations', 'Migrate auth', 'Merge identities')
BrowseCentral labels should include specific context when needed (e.g., 'Configure Scalekit MCP server', 'Validate incoming API requests')
BrowseCentral labels should use integration context when applicable (e.g., 'Build MCP auth with your existing auth system')
BrowseCentral labels should avoid instructional prefixes: 'How to', 'Guide to', 'Implement', 'Configure', 'Learn', 'Understand'
BrowseCentral labels should avoid verbose phrases: 'Step-by-step guide', 'Complete tutorial', 'Detailed documentation'
BrowseCentral labels should avoid weak verbs: 'Enable', 'Allow', 'Provide', 'Support'
Files:
src/content/docs/authenticate/m2m/api-keys.mdx
**/*.{md,mdx}
📄 CodeRabbit inference engine (.cursor/rules/deno-docs-style.mdc)
**/*.{md,mdx}: Use sentence case for all titles and headings in MD/MDX documentation
Keep page titles short and descriptive (3–7 words when possible) in MD/MDX documentation
Use outcome-focused headings that describe results, not categories (e.g., 'Run a script' not 'Scripts')
Avoid gerunds in headings when an imperative works - prefer 'Configure proxies' over 'Configuring proxies'
Keep sidebar labels concise (1–3 words), use sentence case, and focus on outcomes or objects
Use sentence case in sidebar labels without punctuation
Set frontmatter title in sentence case with a clear outcome; description in one sentence (≤160 chars); sidebar.label as shorter form of title; enable tableOfContents on longer pages
Start documentation pages with a one-paragraph overview explaining what the page covers and when to use it
Present the primary use case (80% path) first in documentation, with edge cases later
Use numbered steps for task-focused sections in documentation, with each step beginning with a verb
Break up long documentation sections with subheadings every 3–6 paragraphs
Use asides for important notes, tips, cautions, and references in documentation
Provide runnable, minimal code examples that work as-is in documentation
Prefer CLI-first examples and show file layout when helpful in documentation
Label code blocks with titles for context (e.g., 'Terminal', 'main.ts') in documentation
Keep code block annotations brief and purposeful - annotate only what matters
Use consistent variable and file names across a documentation page
Use descriptive link text in documentation (e.g., 'See permission flags' not 'click here')
Prefer relative links for internal documentation pages and include anchors for section references
Reference APIs consistently using backticks for code, file names, CLI flags, and endpoints
Use backticks for code, file names, CLI flags, and endpoints in documentation
Use lists for options and features in documentation; tables only when comparisons are cleare...
Files:
src/content/docs/authenticate/m2m/api-keys.mdx
🧠 Learnings (28)
📓 Common learnings
Learnt from: saif-at-scalekit
Repo: scalekit-inc/developer-docs PR: 424
File: public/api/scalekit.scalar.json:3451-3457
Timestamp: 2026-02-10T05:32:59.967Z
Learning: In scalekit-inc/developer-docs, the file public/api/scalekit.scalar.json is a generated OpenAPI artifact; reviewers should avoid direct edits. For inconsistencies (e.g., the /api/v1/permissions "type" query param description vs. enum), handle short-term via release/PR notes and track long-term fixes in the generator or source templates rather than modifying the generated JSON.
Learnt from: AkshayParihar33
Repo: scalekit-inc/developer-docs PR: 415
File: src/content/docs/authenticate/fsa/multiapp/native-app.mdx:72-179
Timestamp: 2026-02-02T05:55:51.251Z
Learning: In the `src/content/docs/authenticate/fsa/multiapp/` directory, the multi-app authentication documentation (native-app.mdx, single-page-app.mdx, web-app.mdx, overview.mdx) currently uses conceptual shell/curl examples instead of multi-language SDK code examples because the Scalekit SDKs have not yet been built/updated for multi-app functionality. Once the SDKs are ready, these files should be updated to include all 4 languages (Node.js, Python, Go, Java) using `<Tabs syncKey="tech-stack">`.
Learnt from: CR
Repo: scalekit-inc/developer-docs PR: 0
File: .cursorrules:0-0
Timestamp: 2026-01-13T12:46:55.260Z
Learning: Keep documentation accurate and up-to-date with product changes, updating examples when APIs change
📚 Learning: 2026-02-02T05:55:51.251Z
Learnt from: AkshayParihar33
Repo: scalekit-inc/developer-docs PR: 415
File: src/content/docs/authenticate/fsa/multiapp/native-app.mdx:72-179
Timestamp: 2026-02-02T05:55:51.251Z
Learning: In the `src/content/docs/authenticate/fsa/multiapp/` directory, the multi-app authentication documentation (native-app.mdx, single-page-app.mdx, web-app.mdx, overview.mdx) currently uses conceptual shell/curl examples instead of multi-language SDK code examples because the Scalekit SDKs have not yet been built/updated for multi-app functionality. Once the SDKs are ready, these files should be updated to include all 4 languages (Node.js, Python, Go, Java) using `<Tabs syncKey="tech-stack">`.
Applied to files:
src/content/docs/authenticate/m2m/api-keys.mdx
📚 Learning: 2026-01-13T12:46:55.260Z
Learnt from: CR
Repo: scalekit-inc/developer-docs PR: 0
File: .cursorrules:0-0
Timestamp: 2026-01-13T12:46:55.260Z
Learning: Applies to **/*.mdx : Include context comments explaining what's happening in code: '// Extract encrypted tokens from request cookies', '// Decrypt the access token before validation'
Applied to files:
src/content/docs/authenticate/m2m/api-keys.mdx
📚 Learning: 2026-01-13T12:46:55.260Z
Learnt from: CR
Repo: scalekit-inc/developer-docs PR: 0
File: .cursorrules:0-0
Timestamp: 2026-01-13T12:46:55.260Z
Learning: Applies to **/*.mdx : Use present tense for descriptions: 'Scalekit handles the complex authentication flow', 'The SDK provides methods to refresh tokens'
Applied to files:
src/content/docs/authenticate/m2m/api-keys.mdx
📚 Learning: 2026-01-13T12:46:55.260Z
Learnt from: CR
Repo: scalekit-inc/developer-docs PR: 0
File: .cursorrules:0-0
Timestamp: 2026-01-13T12:46:55.260Z
Learning: Applies to **/*.mdx : Use action verbs in section headings: 'Store session tokens securely', 'Validate the state parameter', 'Exchange authorization code for tokens'
Applied to files:
src/content/docs/authenticate/m2m/api-keys.mdx
📚 Learning: 2026-02-10T05:32:59.967Z
Learnt from: saif-at-scalekit
Repo: scalekit-inc/developer-docs PR: 424
File: public/api/scalekit.scalar.json:3451-3457
Timestamp: 2026-02-10T05:32:59.967Z
Learning: In scalekit-inc/developer-docs, the file public/api/scalekit.scalar.json is a generated OpenAPI artifact; reviewers should avoid direct edits. For inconsistencies (e.g., the /api/v1/permissions "type" query param description vs. enum), handle short-term via release/PR notes and track long-term fixes in the generator or source templates rather than modifying the generated JSON.
Applied to files:
src/content/docs/authenticate/m2m/api-keys.mdx
📚 Learning: 2026-01-13T12:47:52.148Z
Learnt from: CR
Repo: scalekit-inc/developer-docs PR: 0
File: .cursor/rules/deno-docs-style.mdc:0-0
Timestamp: 2026-01-13T12:47:52.148Z
Learning: Applies to **/*.{md,mdx} : Keep sidebar labels concise (1–3 words), use sentence case, and focus on outcomes or objects
Applied to files:
src/content/docs/authenticate/m2m/api-keys.mdx
📚 Learning: 2026-01-13T12:47:52.148Z
Learnt from: CR
Repo: scalekit-inc/developer-docs PR: 0
File: .cursor/rules/deno-docs-style.mdc:0-0
Timestamp: 2026-01-13T12:47:52.148Z
Learning: Applies to **/*.{md,mdx} : Set frontmatter title in sentence case with a clear outcome; description in one sentence (≤160 chars); sidebar.label as shorter form of title; enable tableOfContents on longer pages
Applied to files:
src/content/docs/authenticate/m2m/api-keys.mdx
📚 Learning: 2026-01-13T12:48:19.565Z
Learnt from: CR
Repo: scalekit-inc/developer-docs PR: 0
File: .cursor/rules/expressive-code.mdc:0-0
Timestamp: 2026-01-13T12:48:19.565Z
Learning: Applies to **/*.{md,mdx} : Use sentence case for headings near code examples (e.g., 'Authenticate users')
Applied to files:
src/content/docs/authenticate/m2m/api-keys.mdx
📚 Learning: 2026-01-13T12:46:55.260Z
Learnt from: CR
Repo: scalekit-inc/developer-docs PR: 0
File: .cursorrules:0-0
Timestamp: 2026-01-13T12:46:55.260Z
Learning: Applies to **/*.mdx : Include configuration comments in code examples: '// Get the signing secret from Scalekit dashboard > Interceptors tab'
Applied to files:
src/content/docs/authenticate/m2m/api-keys.mdx
📚 Learning: 2026-01-30T18:20:07.851Z
Learnt from: AkshayParihar33
Repo: scalekit-inc/developer-docs PR: 415
File: src/content/docs/authenticate/fsa/multiapp/native-app.mdx:1-6
Timestamp: 2026-01-30T18:20:07.851Z
Learning: In the scalekit-inc/developer-docs repository, MDX files under `src/content/docs/authenticate/fsa/multiapp/` do not use `order` or `tags` fields in their frontmatter. Ordering and grouping are managed centrally in `src/configs/sidebar.config.ts`.
Applied to files:
src/content/docs/authenticate/m2m/api-keys.mdx
📚 Learning: 2026-01-13T12:46:55.260Z
Learnt from: CR
Repo: scalekit-inc/developer-docs PR: 0
File: .cursorrules:0-0
Timestamp: 2026-01-13T12:46:55.260Z
Learning: Applies to **/*.mdx : Use transition phrases between sections: 'After the user authenticates...', 'Once the state is validated...', 'Let's take a look at how to...'
Applied to files:
src/content/docs/authenticate/m2m/api-keys.mdx
📚 Learning: 2026-01-13T12:47:12.462Z
Learnt from: CR
Repo: scalekit-inc/developer-docs PR: 0
File: .cursor/rules/browsecentral-labels.mdc:0-0
Timestamp: 2026-01-13T12:47:12.462Z
Learning: Applies to **/*.{yml,yaml,md,mdx} : BrowseCentral labels should use 'Action + Object' pattern (e.g., 'Invite users', 'Restrict sign-up', 'Set up SCIM')
Applied to files:
src/content/docs/authenticate/m2m/api-keys.mdx
📚 Learning: 2026-01-13T12:46:55.260Z
Learnt from: CR
Repo: scalekit-inc/developer-docs PR: 0
File: .cursorrules:0-0
Timestamp: 2026-01-13T12:46:55.260Z
Learning: Applies to **/*.mdx : Use consistent SDK variable naming: Node.js='scalekit', Python='scalekit_client', Go='scalekitClient', Java='scalekitClient'
Applied to files:
src/content/docs/authenticate/m2m/api-keys.mdx
📚 Learning: 2026-02-18T02:55:23.285Z
Learnt from: CR
Repo: scalekit-inc/developer-docs PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-02-18T02:55:23.285Z
Learning: Applies to **/*.{md,mdx} : Use SDK variable names: Node.js `scalekit`, Python `scalekit_client`, Go `scalekitClient`, Java `scalekitClient`
Applied to files:
src/content/docs/authenticate/m2m/api-keys.mdx
📚 Learning: 2026-01-13T12:46:55.260Z
Learnt from: CR
Repo: scalekit-inc/developer-docs PR: 0
File: .cursorrules:0-0
Timestamp: 2026-01-13T12:46:55.260Z
Learning: Applies to **/*.mdx : Use future tense for results: 'This will redirect users to...', 'You'll receive a JWT containing...', 'Scalekit returns an authorization code'
Applied to files:
src/content/docs/authenticate/m2m/api-keys.mdx
📚 Learning: 2026-01-13T12:47:33.407Z
Learnt from: CR
Repo: scalekit-inc/developer-docs PR: 0
File: .cursor/rules/comment-standards.mdc:0-0
Timestamp: 2026-01-13T12:47:33.407Z
Learning: Applies to **/*.{js,ts,tsx,jsx,py,java,cs,go,cpp,c,rb,php,swift,kt,scala,rs,m,mm,groovy} : Add comments when fixing bugs - document bug fixes with context about the issue, reference issue trackers and bug reports, and explain workarounds and their limitations
Applied to files:
src/content/docs/authenticate/m2m/api-keys.mdx
📚 Learning: 2026-01-13T12:46:55.260Z
Learnt from: CR
Repo: scalekit-inc/developer-docs PR: 0
File: .cursorrules:0-0
Timestamp: 2026-01-13T12:46:55.260Z
Learning: Applies to **/*.mdx : Include todo/next step comments in code examples: '// TODO: Store user session (next guide covers this)', '// Next step: Create a session and log in the user'
Applied to files:
src/content/docs/authenticate/m2m/api-keys.mdx
📚 Learning: 2026-01-13T12:48:11.566Z
Learnt from: CR
Repo: scalekit-inc/developer-docs PR: 0
File: .cursor/rules/documentation-guide.mdc:0-0
Timestamp: 2026-01-13T12:48:11.566Z
Learning: Applies to **/*.{md,mdx} : Ensure code examples reflect current APIs and are tested when possible
Applied to files:
src/content/docs/authenticate/m2m/api-keys.mdx
📚 Learning: 2026-01-13T12:46:55.260Z
Learnt from: CR
Repo: scalekit-inc/developer-docs PR: 0
File: .cursorrules:0-0
Timestamp: 2026-01-13T12:46:55.260Z
Learning: Applies to **/*.mdx : Always include error handling in code examples showing both success and error paths
Applied to files:
src/content/docs/authenticate/m2m/api-keys.mdx
📚 Learning: 2026-02-18T02:55:23.285Z
Learnt from: CR
Repo: scalekit-inc/developer-docs PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-02-18T02:55:23.285Z
Learning: Applies to **/*.{md,mdx} : Include security comments in code examples explaining threats and security implications
Applied to files:
src/content/docs/authenticate/m2m/api-keys.mdx
📚 Learning: 2026-01-13T12:48:11.566Z
Learnt from: CR
Repo: scalekit-inc/developer-docs PR: 0
File: .cursor/rules/documentation-guide.mdc:0-0
Timestamp: 2026-01-13T12:48:11.566Z
Learning: Applies to **/*.{md,mdx} : Prefer comments explaining intent in code examples, not restating code
Applied to files:
src/content/docs/authenticate/m2m/api-keys.mdx
📚 Learning: 2026-01-13T12:47:33.407Z
Learnt from: CR
Repo: scalekit-inc/developer-docs PR: 0
File: .cursor/rules/comment-standards.mdc:0-0
Timestamp: 2026-01-13T12:47:33.407Z
Learning: Applies to **/*.{js,ts,tsx,jsx,py,java,cs,go,cpp,c,rb,php,swift,kt,scala,rs,m,mm,groovy} : Explain unidiomatic code in comments - comment on code that might seem unnecessary or redundant and document why you chose a specific pattern over more common alternatives, especially when it deviates from team conventions
Applied to files:
src/content/docs/authenticate/m2m/api-keys.mdx
📚 Learning: 2026-01-13T12:46:55.260Z
Learnt from: CR
Repo: scalekit-inc/developer-docs PR: 0
File: .cursorrules:0-0
Timestamp: 2026-01-13T12:46:55.260Z
Learning: Applies to **/*.mdx : Always include security comments in security-related code with pattern: '// Security: ALWAYS verify requests are from Scalekit before processing'
Applied to files:
src/content/docs/authenticate/m2m/api-keys.mdx
📚 Learning: 2026-01-13T12:47:33.407Z
Learnt from: CR
Repo: scalekit-inc/developer-docs PR: 0
File: .cursor/rules/comment-standards.mdc:0-0
Timestamp: 2026-01-13T12:47:33.407Z
Learning: Applies to **/*.{js,ts,tsx,jsx,py,java,cs,go,cpp,c,rb,php,swift,kt,scala,rs,m,mm,groovy} : Use comments to mark incomplete implementations - use standard formats for TODO, FIXME, and NOTE comments with context about what needs to be done and reference issue trackers when possible
Applied to files:
src/content/docs/authenticate/m2m/api-keys.mdx
📚 Learning: 2026-01-13T12:47:33.407Z
Learnt from: CR
Repo: scalekit-inc/developer-docs PR: 0
File: .cursor/rules/comment-standards.mdc:0-0
Timestamp: 2026-01-13T12:47:33.407Z
Learning: Applies to **/*.{js,ts,tsx,jsx,py,java,cs,go,cpp,c,rb,php,swift,kt,scala,rs,m,mm,groovy} : Always document public APIs with function/class comments - explain the purpose, parameters, return values, and exceptions; include usage examples for complex functions
Applied to files:
src/content/docs/authenticate/m2m/api-keys.mdx
📚 Learning: 2026-01-30T18:18:50.883Z
Learnt from: AkshayParihar33
Repo: scalekit-inc/developer-docs PR: 415
File: src/content/docs/authenticate/fsa/multiapp/manage-apps.mdx:31-49
Timestamp: 2026-01-30T18:18:50.883Z
Learning: In all Scalekit documentation files (MDX), treat the terms 'Applications', 'Single Page Application (SPA)', 'Native Application', and 'Web Application' as proper nouns and preserve their capitalization in headings and body text. Ensure these terms remain capitalized even when used in sentence case or within prose.
Applied to files:
src/content/docs/authenticate/m2m/api-keys.mdx
📚 Learning: 2026-02-04T12:47:16.544Z
Learnt from: saif-at-scalekit
Repo: scalekit-inc/developer-docs PR: 412
File: src/content/docs/dev-kit/tools/scalekit-dryrun.mdx:1-23
Timestamp: 2026-02-04T12:47:16.544Z
Learning: In scalekit-inc/developer-docs, the MDX frontmatter field order is required only when the sidebar configuration points to a directory (for auto-generation). If the sidebar.config.ts references a specific file path, the order field is not required. Apply this check to all MDX files under src/content/docs: if a file contributes to an auto-generated sidebar (directory path), ensure order is present; if it’s linked to a concrete file, order can be omitted. Use sidebar.config.ts to determine whether a given MDX file falls under directory-based vs file-specific sidebar references.
Applied to files:
src/content/docs/authenticate/m2m/api-keys.mdx
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@src/content/docs/authenticate/m2m/api-keys.mdx`:
- Line 898: Add the required STYLE-CHECK footer after the final paragraph in the
documentation: append a single line "STYLE-CHECK: TODO" (or "STYLE-CHECK:
PASSED" if ready) at the end of the content in the api-keys.mdx document so the
file ends with that line; locate the end of the final paragraph in the current
content (the line "You now have everything you need to issue, validate, and
manage API keys in your application.") and add the STYLE-CHECK line immediately
after it.
- Around line 27-45: Wrap the existing d2 sequence diagram fenced block (the
```d2 pad=36 ... ``` block) in a collapsible details section: place a <details>
tag above and a </details> tag below, add a <summary> line containing an icon
and short label (e.g., "✏️ Sequence diagram" or similar) and keep the original
fenced diagram content unchanged inside the collapsible; ensure
indentation/whitespace remains valid for MDX so the diagram renders when the
section is expanded.
- Around line 117-197: The headings "Organization-scoped API key" and
"User-scoped API key" are noun phrases—change them to action-oriented headings
(e.g., "Create an organization-scoped API key" and "Create a user-scoped API
key" or "Generate an organization-scoped API key" / "Generate a user-scoped API
key") to follow the guideline "Use action verbs in section headings"; update
both heading lines and any internal links or table-of-contents references that
point to those headings so they remain consistent.
- Around line 60-107: Update all SDK initialization snippets (ScalekitClient,
scalekitClient, scalekit_client, NewScalekitClient) to include brief inline
comments showing where each credential/config value comes from (e.g., "Get the
environment URL and client credentials from your Scalekit dashboard >
Interceptors/Environment settings" or "Set these as environment variables:
SCALEKIT_ENVIRONMENT_URL, SCALEKIT_CLIENT_ID, SCALEKIT_CLIENT_SECRET"); place
the comments immediately above or on the same line as the constructor call in
the Node (ScalekitClient), Python (ScalekitClient), Go (NewScalekitClient) and
Java (ScalekitClient) examples so readers can see the source of each value
without guessing.
- Around line 674-713: Add explicit success and error handling to each token
invalidation example: wrap
scalekit.token.invalidateToken(opaqueToken)/scalekit.token.invalidateToken(tokenId)
in a try/catch (or promise .then/.catch) and log success vs error; for Python
wrap scalekit_client.tokens.invalidate_token(...) in try/except and handle
exceptions/print success; for Go check the returned err from
scalekitClient.Token().InvalidateToken(ctx, ...) and handle/log success or
error; for Java surround scalekitClient.tokens().invalidate(...) with try/catch
(or check thrown exceptions) and log success or failure. Ensure each snippet
shows both the success path and the error/logging path using the same
function/method names shown.
- Around line 303-542: Multiple validation snippets call token validation
without the required security comment; add the standardized comment "//
Security: ALWAYS verify requests are from Scalekit before processing"
immediately above each call to validateToken / scalekit.token.validateToken
(Node.js), scalekit_client.tokens.validate_token (Python),
scalekitClient.Token().ValidateToken (Go), and scalekitClient.tokens().validate
(Java) in the validation, roles, and custom-metadata code blocks so every
security-related validation call includes the mandated comment.
- Around line 124-283: Add a one-line "Use case" comment and a one-line "Next
step/TODO" comment to every create-token example shown (Node.js:
scalekit.token.createToken and scalekit.token.createToken for user-scoped;
Python: scalekit_client.tokens.create_token; Go:
scalekitClient.Token().CreateToken; Java: scalekitClient.tokens().create),
placing the comments immediately above the call and immediately after storing
the returned token respectively; ensure the use-case describes the scenario
(e.g., "Use case: CI/CD pipeline token" or "Use case: per-user deployment
token") and the next-step/TODO indicates what to do with the token (e.g., "TODO:
store token securely; next guide covers session creation").
- Around line 18-68: Add an import for Code from `@astrojs/starlight/components`
below the frontmatter and replace the fenced JS snippet inside the TabItem (the
block that shows ScalekitClient/Express.js) with a <Code> component usage: move
the snippet source into the code prop, set lang="javascript", title="Express.js"
and convert collapse={1-2} into the collapse prop format accepted by <Code>.
Keep the TabItem and surrounding Tabs intact and ensure other fenced blocks with
title/collapse in this file are similarly converted.
---
Duplicate comments:
In `@src/content/docs/authenticate/m2m/api-keys.mdx`:
- Around line 21-23: The opening paragraph uses inconsistent casing ("API keys"
vs "API Keys"), long sentences, and some subject–verb agreement issues; revise
the first block (the paragraph starting "When your customers need to
integrate...") to use consistent "API keys" casing, break long sentences into
shorter ones (<25 words each), fix subject–verb agreement (e.g., ensure verbs
match singular/plural subjects), and simplify phrasing for clarity—keep that the
keys are long-lived, revocable bearer credentials scoped to organization or
user, cannot be validated client-side, must be validated server-side by
Scalekit, and that revocation is immediate; update the subsequent sentence about
claims and scoping similarly for brevity and plain language.
- Around line 725-875: Insert the required security comment "// Security: ALWAYS
verify requests are from Scalekit before processing" immediately adjacent to the
server-side validation call in each middleware example: in the Node.js
authenticateToken function add the comment right before the
scalekit.token.validateToken(token) call; in the Flask authenticate_token
decorator add it just before scalekit_client.tokens.validate_token(...); in the
Go AuthenticateToken handler add it before
scalekitClient.Token().ValidateToken(...); and in the Java
TokenAuthFilter.doFilterInternal method add it immediately before
scalekitClient.tokens().validate(token). Ensure the comment text matches the
required pattern exactly and sits on its own line for each validation call.
- Around line 551-662: Update each language example to include explicit success
and error handling and replace restating comments with intent-focused comments:
for Node.js update usages of scalekit.token.listTokens to handle both resolved
response and caught errors (e.g., try/catch or .then/.catch) and change comments
to explain intent like "fetch first page of tokens for org" and "fetch next page
if present"; for Python update scalekit_client.tokens.list_tokens to check
responses and catch exceptions (try/except) and use intent comments; for Go
update scalekitClient.Token().ListTokens calls to check and handle returned err
values and verify nextPage token before calling again, and use intent comments;
for Java update scalekitClient.tokens().list usages to handle exceptions or
check outcome and document intent rather than restating code. Ensure each
snippet shows both the success path (processing response.tokens) and an error
path (logging or handling the error).
- Around line 1-6: Update the frontmatter of this MDX to include a numeric order
field, enable the table of contents by adding tableOfContents: true, and change
the sidebar label from "Add API Keys" to sentence case "Add API keys"; ensure
title and description meet length guidelines (title ≤60 chars, description ≤160
chars) and keep tags unchanged.
- Around line 891-897: Convert the four bullet tips into CheckItem components
(use the existing CheckItem MDX pattern) so each best-practice becomes a
separate <CheckItem> entry, and replace the plain list with that component-based
checklist; additionally add a short inline example or a one-line code snippet
showing how to set the expiry parameter when creating a key (use the
repository's API method that accepts expiry, referenced as expiry) or add a link
to the relevant API docs, ensuring the example uses the current expiry parameter
name and mirrors other CheckItem usages in the docs.
| import { Aside, Steps, Tabs, TabItem, Card, CardGrid } from '@astrojs/starlight/components'; | ||
| import InstallSDK from '@components/templates/_installsdk.mdx'; | ||
|
|
||
| When your customers need to integrate with your APIs — whether for CI/CD pipelines, partner integrations, or internal tooling — they need a straightforward way to authenticate. Scalekit API keys gives you long-lived, revocable bearer credentials that can be issued to your customers for Organizational or User Level access to your APIs. | ||
|
|
||
| Unlike [JWT-based M2M authentication](/authenticate/m2m/api-auth-quickstart/), API keys do not carry embedded claims and cannot be validated on the client side. The API Keys can be validated via APIs with Scalekit and after server-side validation, the claims are sent when a valid API Key is presented. Revocation of API keys takes effect immediately with no expiry windows or propagation delays. Each key is scoped to an organization and optionally to a specific user, making it easy to build personal access tokens, per-user rate limiting, and audit trails. | ||
|
|
||
| In this guide, you'll learn how to create, validate, list, and revoke API keys using the Scalekit SDK. | ||
|
|
||
| ```d2 pad=36 | ||
| shape: sequence_diagram | ||
|
|
||
| API Client | ||
| User | ||
| Your App | ||
| Scalekit | ||
|
|
||
| User -> Your App: Request API key | ||
| Your App -> Scalekit: Create token (organizationId, userId) | ||
| Scalekit -> Your App: API key + tokenId | ||
| Your App -> User: API key | ||
| User -> API Client: Configure API key | ||
| API Client -> Your App: Request with Authorization header | ||
| Your App -> Scalekit: Validate token | ||
| Scalekit -> Your App: Organization, user, and role info | ||
| Your App -> Your App: Process request | ||
| Your App -> API Client: Response | ||
| ``` | ||
|
|
||
| <Aside type="tip"> | ||
| The plain-text API key is returned **only at creation time**. Scalekit does not store the key and cannot retrieve it later. Instruct your users to copy and store the key securely before closing the creation dialog. | ||
| </Aside> | ||
|
|
||
| ## Install the SDK | ||
|
|
||
| <InstallSDK /> | ||
|
|
||
| Initialize the Scalekit client with your environment credentials: | ||
|
|
||
| <Tabs syncKey="tech-stack"> | ||
| <TabItem value="node" label="Node.js"> | ||
|
|
||
| ```javascript title="Express.js" collapse={1-2} | ||
| import { ScalekitClient } from '@scalekit-sdk/node'; | ||
|
|
||
| const scalekit = new ScalekitClient( | ||
| process.env.SCALEKIT_ENVIRONMENT_URL, | ||
| process.env.SCALEKIT_CLIENT_ID, | ||
| process.env.SCALEKIT_CLIENT_SECRET | ||
| ); | ||
| ``` |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
# Find examples of <Code> usage with title and collapse properties
echo "=== <Code> components with title prop ==="
rg -A 3 '<Code[^>]*title=' src/content/docs -g "*.mdx" | head -40
echo ""
echo "=== <Code> components with collapse prop ==="
rg -A 3 '<Code[^>]*collapse=' src/content/docs -g "*.mdx" | head -40
echo ""
echo "=== Full import statements with Code ==="
rg "import.*Code.*from.*starlight" src/content/docs -g "*.mdx" | head -10Repository: scalekit-inc/developer-docs
Length of output: 1811
🏁 Script executed:
#!/bin/bash
# Find files with Code imports and show their actual usage
echo "=== Files with Code import ==="
rg "import.*Code.*from.*starlight" src/content/docs -g "*.mdx" -l | head -3
echo ""
echo "=== Actual <Code> component usage in first file ==="
rg '<Code' src/content/docs/reference/agent-connectors/zoom.mdx -A 5 | head -40
echo ""
echo "=== Check another file ==="
rg '<Code' src/content/docs/reference/agent-connectors/fathom.mdx -A 5 | head -40Repository: scalekit-inc/developer-docs
Length of output: 349
🏁 Script executed:
#!/bin/bash
# More comprehensive search for Code component usage
echo "=== Search for <Code usage across entire docs ==="
find src/content/docs -name "*.mdx" -exec grep -l "<Code" {} \; 2>/dev/null | head -5
echo ""
echo "=== Check the actual content of files that use Code ==="
find src/content/docs -name "*.mdx" -exec grep -l "<Code" {} \; 2>/dev/null | head -1 | xargs cat | head -100
echo ""
echo "=== Search for fenced code blocks with title attribute ==="
rg '```\w+\s+title=' src/content/docs -g "*.mdx" | head -10
echo ""
echo "=== Current file content around code block ==="
sed -n '45,58p' src/content/docs/authenticate/m2m/api-keys.mdxRepository: scalekit-inc/developer-docs
Length of output: 1620
🏁 Script executed:
#!/bin/bash
# Check one of the files using fenced code with title/collapse
echo "=== Check sso/quickstart.mdx import statement ==="
head -5 src/content/docs/sso/quickstart.mdx
echo ""
echo "=== Check if it imports Code ==="
rg "import.*Code" src/content/docs/sso/quickstart.mdx
echo ""
echo "=== Show a code block example from that file ==="
sed -n '95,105p' src/content/docs/sso/quickstart.mdx
echo ""
echo "=== Check api-keys.mdx import ==="
head -5 src/content/docs/authenticate/m2m/api-keys.mdxRepository: scalekit-inc/developer-docs
Length of output: 1152
🏁 Script executed:
#!/bin/bash
# Check for Expressive Code configuration or documentation in the repo
echo "=== Look for expressive-code config ==="
find . -name "*expressive*" -o -name "astro.config*" | head -10
echo ""
echo "=== Check astro.config for expressive code ==="
rg "expressive" . --type js --type ts 2>/dev/null | head -20
echo ""
echo "=== Check package.json for expressive-code ==="
rg "expressive" package.json
echo ""
echo "=== Look at the actual fenced syntax being used ==="
sed -n '48,54p' src/content/docs/authenticate/m2m/api-keys.mdx
</parameter>Repository: scalekit-inc/developer-docs
Length of output: 820
🏁 Script executed:
#!/bin/bash
# Read the expressive-code rule file
echo "=== Content of expressive-code.mdc ==="
cat .cursor/rules/expressive-code.mdc
echo ""
echo "=== Check the actual code block in api-keys.mdx ==="
sed -n '48,55p' src/content/docs/authenticate/m2m/api-keys.mdxRepository: scalekit-inc/developer-docs
Length of output: 3408
Import Code from @astrojs/starlight/components and convert fenced code blocks with title and collapse attributes to use the <Code> component.
The code block at lines 48–54 uses a fenced syntax with title="Express.js" and collapse={1-2}, but per the Expressive Code guidelines, snippets with titles should use Starlight's <Code> component instead. Add the import below the frontmatter and refactor the snippet to use <Code code={...} lang="javascript" title="Express.js" collapse={...} /> (or similar structure for other code blocks in this file).
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@src/content/docs/authenticate/m2m/api-keys.mdx` around lines 18 - 68, Add an
import for Code from `@astrojs/starlight/components` below the frontmatter and
replace the fenced JS snippet inside the TabItem (the block that shows
ScalekitClient/Express.js) with a <Code> component usage: move the snippet
source into the code prop, set lang="javascript", title="Express.js" and convert
collapse={1-2} into the collapse prop format accepted by <Code>. Keep the
TabItem and surrounding Tabs intact and ensure other fenced blocks with
title/collapse in this file are similarly converted.
| ```d2 pad=36 | ||
| shape: sequence_diagram | ||
|
|
||
| API Client | ||
| User | ||
| Your App | ||
| Scalekit | ||
|
|
||
| User -> Your App: Request API key | ||
| Your App -> Scalekit: Create token (organizationId, userId) | ||
| Scalekit -> Your App: API key + tokenId | ||
| Your App -> User: API key | ||
| User -> API Client: Configure API key | ||
| API Client -> Your App: Request with Authorization header | ||
| Your App -> Scalekit: Validate token | ||
| Scalekit -> Your App: Organization, user, and role info | ||
| Your App -> Your App: Process request | ||
| Your App -> API Client: Response | ||
| ``` |
There was a problem hiding this comment.
Place the sequence diagram in a collapsible section.
Diagrams in the introduction should be collapsible with an icon.
✏️ Suggested wrapper
+<details>
+ <summary>🧭 API key lifecycle</summary>
+ ...
+</details>As per coding guidelines: "Use collapsible sections in introduction for sequence diagrams, video demonstrations, data models, and JSON examples with appropriate icons".
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@src/content/docs/authenticate/m2m/api-keys.mdx` around lines 27 - 45, Wrap
the existing d2 sequence diagram fenced block (the ```d2 pad=36 ... ``` block)
in a collapsible details section: place a <details> tag above and a </details>
tag below, add a <summary> line containing an icon and short label (e.g., "✏️
Sequence diagram" or similar) and keep the original fenced diagram content
unchanged inside the collapsible; ensure indentation/whitespace remains valid
for MDX so the diagram renders when the section is expanded.
| ```javascript title="Express.js" collapse={1-2} | ||
| import { ScalekitClient } from '@scalekit-sdk/node'; | ||
|
|
||
| const scalekit = new ScalekitClient( | ||
| process.env.SCALEKIT_ENVIRONMENT_URL, | ||
| process.env.SCALEKIT_CLIENT_ID, | ||
| process.env.SCALEKIT_CLIENT_SECRET | ||
| ); | ||
| ``` | ||
|
|
||
| </TabItem> | ||
| <TabItem value="python" label="Python"> | ||
|
|
||
| ```python title="Flask" collapse={1-2} | ||
| import os | ||
| from scalekit import ScalekitClient | ||
|
|
||
| scalekit_client = ScalekitClient( | ||
| env_url=os.environ["SCALEKIT_ENVIRONMENT_URL"], | ||
| client_id=os.environ["SCALEKIT_CLIENT_ID"], | ||
| client_secret=os.environ["SCALEKIT_CLIENT_SECRET"], | ||
| ) | ||
| ``` | ||
|
|
||
| </TabItem> | ||
| <TabItem value="go" label="Go"> | ||
|
|
||
| ```go title="Gin" collapse={1-2} | ||
| import scalekit "github.com/scalekit-inc/scalekit-sdk-go/v2" | ||
|
|
||
| scalekitClient := scalekit.NewScalekitClient( | ||
| os.Getenv("SCALEKIT_ENVIRONMENT_URL"), | ||
| os.Getenv("SCALEKIT_CLIENT_ID"), | ||
| os.Getenv("SCALEKIT_CLIENT_SECRET"), | ||
| ) | ||
| ``` | ||
|
|
||
| </TabItem> | ||
| <TabItem value="java" label="Java"> | ||
|
|
||
| ```java title="Spring Boot" collapse={1-2} | ||
| import com.scalekit.ScalekitClient; | ||
|
|
||
| ScalekitClient scalekitClient = new ScalekitClient( | ||
| System.getenv("SCALEKIT_ENVIRONMENT_URL"), | ||
| System.getenv("SCALEKIT_CLIENT_ID"), | ||
| System.getenv("SCALEKIT_CLIENT_SECRET") | ||
| ); |
There was a problem hiding this comment.
Add configuration context comments in SDK initialization snippets.
Call out where the credentials come from so readers don’t need to guess.
✏️ Example (Node.js)
-const scalekit = new ScalekitClient(
+// Get the environment URL, client ID, and secret from the Scalekit dashboard
+const scalekit = new ScalekitClient(
process.env.SCALEKIT_ENVIRONMENT_URL,
process.env.SCALEKIT_CLIENT_ID,
process.env.SCALEKIT_CLIENT_SECRET
);As per coding guidelines: "Include configuration comments in code examples: '// Get the signing secret from Scalekit dashboard > Interceptors tab'".
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@src/content/docs/authenticate/m2m/api-keys.mdx` around lines 60 - 107, Update
all SDK initialization snippets (ScalekitClient, scalekitClient,
scalekit_client, NewScalekitClient) to include brief inline comments showing
where each credential/config value comes from (e.g., "Get the environment URL
and client credentials from your Scalekit dashboard > Interceptors/Environment
settings" or "Set these as environment variables: SCALEKIT_ENVIRONMENT_URL,
SCALEKIT_CLIENT_ID, SCALEKIT_CLIENT_SECRET"); place the comments immediately
above or on the same line as the constructor call in the Node (ScalekitClient),
Python (ScalekitClient), Go (NewScalekitClient) and Java (ScalekitClient)
examples so readers can see the source of each value without guessing.
| ### Organization-scoped API key | ||
|
|
||
| Create an API key scoped to an organization. This is the most common pattern for service-to-service integrations where the API key represents access on behalf of an entire organization. | ||
|
|
||
| <Tabs syncKey="tech-stack"> | ||
| <TabItem value="node" label="Node.js"> | ||
|
|
||
| ```javascript | ||
| try { | ||
| const response = await scalekit.token.createToken(organizationId, { | ||
| description: 'CI/CD pipeline token', | ||
| }); | ||
|
|
||
| // Store securely — this value cannot be retrieved again after creation | ||
| const opaqueToken = response.token; | ||
| // Stable identifier for management operations (format: apit_xxxxx) | ||
| const tokenId = response.tokenId; | ||
| } catch (error) { | ||
| console.error('Failed to create token:', error.message); | ||
| } | ||
| ``` | ||
|
|
||
| </TabItem> | ||
| <TabItem value="python" label="Python"> | ||
|
|
||
| ```python | ||
| try: | ||
| response = scalekit_client.tokens.create_token( | ||
| organization_id=organization_id, | ||
| description="CI/CD pipeline token", | ||
| ) | ||
|
|
||
| # SDK returns (response, metadata) tuple — access response at index 0 | ||
| opaque_token = response[0].token # store this securely | ||
| token_id = response[0].token_id # format: apit_xxxxx | ||
| except Exception as e: | ||
| print(f"Failed to create token: {e}") | ||
| ``` | ||
|
|
||
| </TabItem> | ||
| <TabItem value="go" label="Go"> | ||
|
|
||
| ```go | ||
| response, err := scalekitClient.Token().CreateToken( | ||
| ctx, organizationId, scalekit.CreateTokenOptions{ | ||
| Description: "CI/CD pipeline token", | ||
| }, | ||
| ) | ||
| if err != nil { | ||
| log.Printf("Failed to create token: %v", err) | ||
| return | ||
| } | ||
|
|
||
| // Store securely — this value cannot be retrieved again after creation | ||
| opaqueToken := response.Token | ||
| // Stable identifier for management operations (format: apit_xxxxx) | ||
| tokenId := response.TokenId | ||
| ``` | ||
|
|
||
| </TabItem> | ||
| <TabItem value="java" label="Java"> | ||
|
|
||
| ```java | ||
| try { | ||
| CreateTokenResponse response = scalekitClient.tokens().create(organizationId); | ||
|
|
||
| // Store securely — this value cannot be retrieved again after creation | ||
| String opaqueToken = response.getToken(); | ||
| // Stable identifier for management operations (format: apit_xxxxx) | ||
| String tokenId = response.getTokenId(); | ||
| } catch (Exception e) { | ||
| System.err.println("Failed to create token: " + e.getMessage()); | ||
| } | ||
| ``` | ||
|
|
||
| </TabItem> | ||
| </Tabs> | ||
|
|
||
| ### User-scoped API key | ||
|
|
||
| Scope an API key to a specific user within an organization to enable personal access tokens, per-user audit trails, and user-level rate limiting. You can also attach custom claims as key-value metadata. |
There was a problem hiding this comment.
Make scope headings action‑oriented.
These headings are noun phrases; convert them to action verbs.
✏️ Suggested headings
-### Organization-scoped API key
+### Create an organization-scoped API key
...
-### User-scoped API key
+### Create a user-scoped API keyAs per coding guidelines: "Use action verbs in section headings".
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@src/content/docs/authenticate/m2m/api-keys.mdx` around lines 117 - 197, The
headings "Organization-scoped API key" and "User-scoped API key" are noun
phrases—change them to action-oriented headings (e.g., "Create an
organization-scoped API key" and "Create a user-scoped API key" or "Generate an
organization-scoped API key" / "Generate a user-scoped API key") to follow the
guideline "Use action verbs in section headings"; update both heading lines and
any internal links or table-of-contents references that point to those headings
so they remain consistent.
| ```javascript | ||
| try { | ||
| const response = await scalekit.token.createToken(organizationId, { | ||
| description: 'CI/CD pipeline token', | ||
| }); | ||
|
|
||
| // Store securely — this value cannot be retrieved again after creation | ||
| const opaqueToken = response.token; | ||
| // Stable identifier for management operations (format: apit_xxxxx) | ||
| const tokenId = response.tokenId; | ||
| } catch (error) { | ||
| console.error('Failed to create token:', error.message); | ||
| } | ||
| ``` | ||
|
|
||
| </TabItem> | ||
| <TabItem value="python" label="Python"> | ||
|
|
||
| ```python | ||
| try: | ||
| response = scalekit_client.tokens.create_token( | ||
| organization_id=organization_id, | ||
| description="CI/CD pipeline token", | ||
| ) | ||
|
|
||
| # SDK returns (response, metadata) tuple — access response at index 0 | ||
| opaque_token = response[0].token # store this securely | ||
| token_id = response[0].token_id # format: apit_xxxxx | ||
| except Exception as e: | ||
| print(f"Failed to create token: {e}") | ||
| ``` | ||
|
|
||
| </TabItem> | ||
| <TabItem value="go" label="Go"> | ||
|
|
||
| ```go | ||
| response, err := scalekitClient.Token().CreateToken( | ||
| ctx, organizationId, scalekit.CreateTokenOptions{ | ||
| Description: "CI/CD pipeline token", | ||
| }, | ||
| ) | ||
| if err != nil { | ||
| log.Printf("Failed to create token: %v", err) | ||
| return | ||
| } | ||
|
|
||
| // Store securely — this value cannot be retrieved again after creation | ||
| opaqueToken := response.Token | ||
| // Stable identifier for management operations (format: apit_xxxxx) | ||
| tokenId := response.TokenId | ||
| ``` | ||
|
|
||
| </TabItem> | ||
| <TabItem value="java" label="Java"> | ||
|
|
||
| ```java | ||
| try { | ||
| CreateTokenResponse response = scalekitClient.tokens().create(organizationId); | ||
|
|
||
| // Store securely — this value cannot be retrieved again after creation | ||
| String opaqueToken = response.getToken(); | ||
| // Stable identifier for management operations (format: apit_xxxxx) | ||
| String tokenId = response.getTokenId(); | ||
| } catch (Exception e) { | ||
| System.err.println("Failed to create token: " + e.getMessage()); | ||
| } | ||
| ``` | ||
|
|
||
| </TabItem> | ||
| </Tabs> | ||
|
|
||
| ### User-scoped API key | ||
|
|
||
| Scope an API key to a specific user within an organization to enable personal access tokens, per-user audit trails, and user-level rate limiting. You can also attach custom claims as key-value metadata. | ||
|
|
||
| <Tabs syncKey="tech-stack"> | ||
| <TabItem value="node" label="Node.js"> | ||
|
|
||
| ```javascript | ||
| try { | ||
| const userToken = await scalekit.token.createToken(organizationId, { | ||
| userId: 'usr_12345', | ||
| customClaims: { | ||
| team: 'engineering', | ||
| environment: 'production', | ||
| }, | ||
| description: 'Deployment service token', | ||
| }); | ||
|
|
||
| const opaqueToken = userToken.token; | ||
| const tokenId = userToken.tokenId; | ||
| } catch (error) { | ||
| console.error('Failed to create token:', error.message); | ||
| } | ||
| ``` | ||
|
|
||
| </TabItem> | ||
| <TabItem value="python" label="Python"> | ||
|
|
||
| ```python | ||
| try: | ||
| user_token = scalekit_client.tokens.create_token( | ||
| organization_id=organization_id, | ||
| user_id="usr_12345", | ||
| custom_claims={ | ||
| "team": "engineering", | ||
| "environment": "production", | ||
| }, | ||
| description="Deployment service token", | ||
| ) | ||
|
|
||
| opaque_token = user_token[0].token | ||
| token_id = user_token[0].token_id | ||
| except Exception as e: | ||
| print(f"Failed to create token: {e}") | ||
| ``` | ||
|
|
||
| </TabItem> | ||
| <TabItem value="go" label="Go"> | ||
|
|
||
| ```go | ||
| userToken, err := scalekitClient.Token().CreateToken( | ||
| ctx, organizationId, scalekit.CreateTokenOptions{ | ||
| UserId: "usr_12345", | ||
| CustomClaims: map[string]string{ | ||
| "team": "engineering", | ||
| "environment": "production", | ||
| }, | ||
| Description: "Deployment service token", | ||
| }, | ||
| ) | ||
| if err != nil { | ||
| log.Printf("Failed to create user token: %v", err) | ||
| return | ||
| } | ||
|
|
||
| opaqueToken := userToken.Token | ||
| tokenId := userToken.TokenId | ||
| ``` | ||
|
|
||
| </TabItem> | ||
| <TabItem value="java" label="Java"> | ||
|
|
||
| ```java | ||
| try { | ||
| Map<String, String> customClaims = Map.of( | ||
| "team", "engineering", | ||
| "environment", "production" | ||
| ); | ||
|
|
||
| CreateTokenResponse userToken = scalekitClient.tokens().create( | ||
| organizationId, "usr_12345", customClaims, null, "Deployment service token" | ||
| ); | ||
|
|
||
| String opaqueToken = userToken.getToken(); | ||
| String tokenId = userToken.getTokenId(); | ||
| } catch (Exception e) { | ||
| System.err.println("Failed to create token: " + e.getMessage()); | ||
| } | ||
| ``` |
There was a problem hiding this comment.
Add required use‑case and next‑step comments to create‑token snippets.
Each code example should include a use‑case comment and a next‑step/TODO comment.
✏️ Example (Node.js)
try {
+ // Use case: Issue a CI/CD token for automated deployments
const response = await scalekit.token.createToken(organizationId, {
description: 'CI/CD pipeline token',
});
...
const tokenId = response.tokenId;
+ // Next step: Store tokenId and show the key once to the user
} catch (error) {As per coding guidelines: "Include use case comments explaining scenarios in code examples: '// Use case: Provision a workspace after a sales-assisted onboarding'" and "Include todo/next step comments in code examples: '// TODO: Store user session (next guide covers this)', '// Next step: Create a session and log in the user'".
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@src/content/docs/authenticate/m2m/api-keys.mdx` around lines 124 - 283, Add a
one-line "Use case" comment and a one-line "Next step/TODO" comment to every
create-token example shown (Node.js: scalekit.token.createToken and
scalekit.token.createToken for user-scoped; Python:
scalekit_client.tokens.create_token; Go: scalekitClient.Token().CreateToken;
Java: scalekitClient.tokens().create), placing the comments immediately above
the call and immediately after storing the returned token respectively; ensure
the use-case describes the scenario (e.g., "Use case: CI/CD pipeline token" or
"Use case: per-user deployment token") and the next-step/TODO indicates what to
do with the token (e.g., "TODO: store token securely; next guide covers session
creation").
| ```javascript | ||
| import { ScalekitValidateTokenFailureException } from '@scalekit-sdk/node'; | ||
|
|
||
| try { | ||
| const result = await scalekit.token.validateToken(opaqueToken); | ||
|
|
||
| const orgId = result.tokenInfo?.organizationId; | ||
| const userId = result.tokenInfo?.userId; | ||
| const claims = result.tokenInfo?.customClaims; | ||
| } catch (error) { | ||
| if (error instanceof ScalekitValidateTokenFailureException) { | ||
| // Token is invalid, expired, or revoked | ||
| console.error('Token validation failed:', error.message); | ||
| } | ||
| } | ||
| ``` | ||
|
|
||
| </TabItem> | ||
| <TabItem value="python" label="Python"> | ||
|
|
||
| ```python | ||
| from scalekit import ScalekitValidateTokenFailureException | ||
|
|
||
| try: | ||
| result = scalekit_client.tokens.validate_token(token=opaque_token) | ||
|
|
||
| org_id = result[0].token_info.organization_id | ||
| user_id = result[0].token_info.user_id | ||
| claims = result[0].token_info.custom_claims | ||
| except ScalekitValidateTokenFailureException: | ||
| # Token is invalid, expired, or revoked | ||
| print("Token validation failed") | ||
| ``` | ||
|
|
||
| </TabItem> | ||
| <TabItem value="go" label="Go"> | ||
|
|
||
| ```go | ||
| result, err := scalekitClient.Token().ValidateToken(ctx, opaqueToken) | ||
| if errors.Is(err, scalekit.ErrTokenValidationFailed) { | ||
| // Token is invalid, expired, or revoked | ||
| log.Printf("Token validation failed: %v", err) | ||
| return | ||
| } | ||
|
|
||
| orgId := result.TokenInfo.OrganizationId | ||
| userId := result.TokenInfo.GetUserId() // *string — nil for org-scoped tokens | ||
| claims := result.TokenInfo.CustomClaims | ||
| ``` | ||
|
|
||
| </TabItem> | ||
| <TabItem value="java" label="Java"> | ||
|
|
||
| ```java | ||
| import com.scalekit.exceptions.TokenInvalidException; | ||
|
|
||
| try { | ||
| ValidateTokenResponse result = scalekitClient.tokens().validate(opaqueToken); | ||
|
|
||
| String orgId = result.getTokenInfo().getOrganizationId(); | ||
| String userId = result.getTokenInfo().getUserId(); | ||
| Map<String, String> claims = result.getTokenInfo().getCustomClaimsMap(); | ||
| } catch (TokenInvalidException e) { | ||
| // Token is invalid, expired, or revoked | ||
| System.err.println("Token validation failed: " + e.getMessage()); | ||
| } | ||
| ``` | ||
|
|
||
| </TabItem> | ||
| </Tabs> | ||
|
|
||
| If the API key is invalid, expired, or has been revoked, validation fails with a specific error that you can catch and handle in your code. This makes it easy to reject unauthorized requests in your API middleware. | ||
|
|
||
| ### Access roles and organization details | ||
|
|
||
| Beyond the basic organization and user information, the validation response also includes any roles assigned to the user and external identifiers you've configured for the organization. These are useful for making authorization decisions without additional database lookups. | ||
|
|
||
| <Tabs syncKey="tech-stack"> | ||
| <TabItem value="node" label="Node.js"> | ||
|
|
||
| ```javascript | ||
| try { | ||
| const result = await scalekit.token.validateToken(opaqueToken); | ||
|
|
||
| // Roles assigned to the user | ||
| const roles = result.tokenInfo?.roles; | ||
|
|
||
| // External identifiers for mapping to your system | ||
| const externalOrgId = result.tokenInfo?.organizationExternalId; | ||
| const externalUserId = result.tokenInfo?.userExternalId; | ||
| } catch (error) { | ||
| if (error instanceof ScalekitValidateTokenFailureException) { | ||
| console.error('Token validation failed:', error.message); | ||
| } | ||
| } | ||
| ``` | ||
|
|
||
| </TabItem> | ||
| <TabItem value="python" label="Python"> | ||
|
|
||
| ```python | ||
| try: | ||
| result = scalekit_client.tokens.validate_token(token=opaque_token) | ||
|
|
||
| # Roles assigned to the user | ||
| roles = result[0].token_info.roles | ||
|
|
||
| # External identifiers for mapping to your system | ||
| external_org_id = result[0].token_info.organization_external_id | ||
| external_user_id = result[0].token_info.user_external_id | ||
| except ScalekitValidateTokenFailureException: | ||
| print("Token validation failed") | ||
| ``` | ||
|
|
||
| </TabItem> | ||
| <TabItem value="go" label="Go"> | ||
|
|
||
| ```go | ||
| result, err := scalekitClient.Token().ValidateToken(ctx, opaqueToken) | ||
| if errors.Is(err, scalekit.ErrTokenValidationFailed) { | ||
| log.Printf("Token validation failed: %v", err) | ||
| return | ||
| } | ||
|
|
||
| // Roles assigned to the user | ||
| roles := result.TokenInfo.Roles | ||
|
|
||
| // External identifiers for mapping to your system | ||
| externalOrgId := result.TokenInfo.OrganizationExternalId | ||
| externalUserId := result.TokenInfo.GetUserExternalId() // *string — nil if no external ID | ||
| ``` | ||
|
|
||
| </TabItem> | ||
| <TabItem value="java" label="Java"> | ||
|
|
||
| ```java | ||
| try { | ||
| ValidateTokenResponse result = scalekitClient.tokens().validate(opaqueToken); | ||
|
|
||
| // Roles assigned to the user | ||
| List<String> roles = result.getTokenInfo().getRolesList(); | ||
|
|
||
| // External identifiers for mapping to your system | ||
| String externalOrgId = result.getTokenInfo().getOrganizationExternalId(); | ||
| String externalUserId = result.getTokenInfo().getUserExternalId(); | ||
| } catch (TokenInvalidException e) { | ||
| System.err.println("Token validation failed: " + e.getMessage()); | ||
| } | ||
| ``` | ||
|
|
||
| </TabItem> | ||
| </Tabs> | ||
|
|
||
| <Aside type="note"> | ||
| Roles are available when you use [Full Stack Authentication](/authenticate/fsa/quickstart/) with [role-based access control](/authenticate/authz/overview/). Assign roles to users through the Scalekit dashboard or API. | ||
| </Aside> | ||
|
|
||
| ### Access custom metadata | ||
|
|
||
| If you attached custom claims when creating the API key, they come back in every validation response. This is a convenient way to make fine-grained authorization decisions — like restricting access by team or environment — without hitting your database. | ||
|
|
||
| <Tabs syncKey="tech-stack"> | ||
| <TabItem value="node" label="Node.js"> | ||
|
|
||
| ```javascript | ||
| try { | ||
| const result = await scalekit.token.validateToken(opaqueToken); | ||
|
|
||
| const team = result.tokenInfo?.customClaims?.team; | ||
| const environment = result.tokenInfo?.customClaims?.environment; | ||
|
|
||
| // Use metadata for authorization | ||
| if (environment !== 'production') { | ||
| return res.status(403).json({ error: 'Production access required' }); | ||
| } | ||
| } catch (error) { | ||
| if (error instanceof ScalekitValidateTokenFailureException) { | ||
| console.error('Token validation failed:', error.message); | ||
| } | ||
| } | ||
| ``` | ||
|
|
||
| </TabItem> | ||
| <TabItem value="python" label="Python"> | ||
|
|
||
| ```python | ||
| try: | ||
| result = scalekit_client.tokens.validate_token(token=opaque_token) | ||
|
|
||
| team = result[0].token_info.custom_claims.get("team") | ||
| environment = result[0].token_info.custom_claims.get("environment") | ||
|
|
||
| # Use metadata for authorization | ||
| if environment != "production": | ||
| return jsonify({"error": "Production access required"}), 403 | ||
| except ScalekitValidateTokenFailureException: | ||
| print("Token validation failed") | ||
| ``` | ||
|
|
||
| </TabItem> | ||
| <TabItem value="go" label="Go"> | ||
|
|
||
| ```go | ||
| result, err := scalekitClient.Token().ValidateToken(ctx, opaqueToken) | ||
| if errors.Is(err, scalekit.ErrTokenValidationFailed) { | ||
| log.Printf("Token validation failed: %v", err) | ||
| return | ||
| } | ||
|
|
||
| team := result.TokenInfo.CustomClaims["team"] | ||
| environment := result.TokenInfo.CustomClaims["environment"] | ||
|
|
||
| // Use metadata for authorization | ||
| if environment != "production" { | ||
| c.JSON(403, gin.H{"error": "Production access required"}) | ||
| return | ||
| } | ||
| ``` | ||
|
|
||
| </TabItem> | ||
| <TabItem value="java" label="Java"> | ||
|
|
||
| ```java | ||
| try { | ||
| ValidateTokenResponse result = scalekitClient.tokens().validate(opaqueToken); | ||
|
|
||
| String team = result.getTokenInfo().getCustomClaimsMap().get("team"); | ||
| String environment = result.getTokenInfo().getCustomClaimsMap().get("environment"); | ||
|
|
||
| // Use metadata for authorization | ||
| if (!"production".equals(environment)) { | ||
| return ResponseEntity.status(403).body(Map.of("error", "Production access required")); | ||
| } | ||
| } catch (TokenInvalidException e) { | ||
| System.err.println("Token validation failed: " + e.getMessage()); | ||
| } | ||
| ``` | ||
|
|
||
| </TabItem> | ||
| </Tabs> |
There was a problem hiding this comment.
Insert the standard security comment before each validation call.
Add the required security comment near each validateToken call in the validation, roles, and custom-metadata snippets.
✏️ Example (Node.js)
try {
+ // Security: ALWAYS verify requests are from Scalekit before processing
const result = await scalekit.token.validateToken(opaqueToken);As per coding guidelines: "Always include security comments in security-related code with pattern: '// Security: ALWAYS verify requests are from Scalekit before processing'".
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@src/content/docs/authenticate/m2m/api-keys.mdx` around lines 303 - 542,
Multiple validation snippets call token validation without the required security
comment; add the standardized comment "// Security: ALWAYS verify requests are
from Scalekit before processing" immediately above each call to validateToken /
scalekit.token.validateToken (Node.js), scalekit_client.tokens.validate_token
(Python), scalekitClient.Token().ValidateToken (Go), and
scalekitClient.tokens().validate (Java) in the validation, roles, and
custom-metadata code blocks so every security-related validation call includes
the mandated comment.
| - **Use custom claims for context**: Attach metadata like `team`, `environment`, or `service` as custom claims. Your API middleware can use these claims for fine-grained authorization without additional database lookups. | ||
| - **Rotate keys safely**: To rotate an API key, create a new key, update the consuming service to use the new key, verify the new key works, then invalidate the old key. This avoids downtime during rotation. | ||
|
|
||
| You now have everything you need to issue, validate, and manage API keys in your application. No newline at end of file |
There was a problem hiding this comment.
Add the required STYLE-CHECK line at the end.
Include a STYLE-CHECK: TODO (or PASSED) line after the final paragraph.
✏️ Suggested footer
-You now have everything you need to issue, validate, and manage API keys in your application.
+You now have everything you need to issue, validate, and manage API keys in your application.
+STYLE-CHECK: TODOAs per coding guidelines: "Include a STYLE-CHECK: [PASSED | TODO] line at the end of every documentation draft".
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@src/content/docs/authenticate/m2m/api-keys.mdx` at line 898, Add the required
STYLE-CHECK footer after the final paragraph in the documentation: append a
single line "STYLE-CHECK: TODO" (or "STYLE-CHECK: PASSED" if ready) at the end
of the content in the api-keys.mdx document so the file ends with that line;
locate the end of the final paragraph in the current content (the line "You now
have everything you need to issue, validate, and manage API keys in your
application.") and add the STYLE-CHECK line immediately after it.
There was a problem hiding this comment.
Actionable comments posted: 1
📜 Review details
Configuration used: Repository UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (1)
src/content/docs/authenticate/m2m/api-keys.mdx
🧰 Additional context used
📓 Path-based instructions (3)
**/*.mdx
📄 CodeRabbit inference engine (.cursorrules)
**/*.mdx: Use clear, descriptive titles that explain the purpose of the document
Include comprehensive descriptions in frontmatter metadata
Organize content with logical heading hierarchy (H2, H3, H4)
Use tableOfContents property in frontmatter when content has multiple sections
Set appropriate sidebar labels for navigation in frontmatter
Use direct instruction writing style with phrases like 'This guide shows you how to...' and 'Create an authorization URL to...'
Use second person perspective ('your application', 'you receive', 'you must') in documentation
Keep sentences concise, aiming for under 25 words per sentence
Explain the 'why' in documentation with phrases like 'This prevents CSRF attacks by...' or 'Use this to validate that...'
Use action verbs in section headings: 'Store session tokens securely', 'Validate the state parameter', 'Exchange authorization code for tokens'
Use present tense for descriptions: 'Scalekit handles the complex authentication flow', 'The SDK provides methods to refresh tokens'
Use future tense for results: 'This will redirect users to...', 'You'll receive a JWT containing...', 'Scalekit returns an authorization code'
Use transition phrases between sections: 'After the user authenticates...', 'Once the state is validated...', 'Let's take a look at how to...'
Write 1-3 opening paragraphs that explain what users will accomplish, provide context about when/why, preview key concepts, and use direct instructional language
Begin introduction sections with a clear statement of what the guide covers and explain the problem being solved
Use collapsible sections in introduction for sequence diagrams, video demonstrations, data models, and JSON examples with appropriate icons
Use numbered format within Steps component:1. ## Titlewith all step content indented with exactly 3 spaces
Use action-oriented headings in step-by-step guides within Steps components
Include code examples in all 4 languages (Node.js, Python, Go, Java) within Steps co...
Files:
src/content/docs/authenticate/m2m/api-keys.mdx
**/*.{yml,yaml,md,mdx}
📄 CodeRabbit inference engine (.cursor/rules/browsecentral-labels.mdc)
**/*.{yml,yaml,md,mdx}: BrowseCentral labels should be maximum 3-5 words - keep concise but add context when needed
BrowseCentral labels should be action-oriented - start with verbs when possible
BrowseCentral labels should be specific and clear - add context when simple labels are ambiguous
BrowseCentral labels should be outcome-focused - describe what users accomplish and the context
BrowseCentral labels should use 'Action + Object' pattern (e.g., 'Invite users', 'Restrict sign-up', 'Set up SCIM')
BrowseCentral labels should use feature names (e.g., 'Enterprise SSO', 'Passwordless quickstart')
BrowseCentral labels should describe task completion (e.g., 'Run migrations', 'Migrate auth', 'Merge identities')
BrowseCentral labels should include specific context when needed (e.g., 'Configure Scalekit MCP server', 'Validate incoming API requests')
BrowseCentral labels should use integration context when applicable (e.g., 'Build MCP auth with your existing auth system')
BrowseCentral labels should avoid instructional prefixes: 'How to', 'Guide to', 'Implement', 'Configure', 'Learn', 'Understand'
BrowseCentral labels should avoid verbose phrases: 'Step-by-step guide', 'Complete tutorial', 'Detailed documentation'
BrowseCentral labels should avoid weak verbs: 'Enable', 'Allow', 'Provide', 'Support'
Files:
src/content/docs/authenticate/m2m/api-keys.mdx
**/*.{md,mdx}
📄 CodeRabbit inference engine (.cursor/rules/deno-docs-style.mdc)
**/*.{md,mdx}: Use sentence case for all titles and headings in MD/MDX documentation
Keep page titles short and descriptive (3–7 words when possible) in MD/MDX documentation
Use outcome-focused headings that describe results, not categories (e.g., 'Run a script' not 'Scripts')
Avoid gerunds in headings when an imperative works - prefer 'Configure proxies' over 'Configuring proxies'
Keep sidebar labels concise (1–3 words), use sentence case, and focus on outcomes or objects
Use sentence case in sidebar labels without punctuation
Set frontmatter title in sentence case with a clear outcome; description in one sentence (≤160 chars); sidebar.label as shorter form of title; enable tableOfContents on longer pages
Start documentation pages with a one-paragraph overview explaining what the page covers and when to use it
Present the primary use case (80% path) first in documentation, with edge cases later
Use numbered steps for task-focused sections in documentation, with each step beginning with a verb
Break up long documentation sections with subheadings every 3–6 paragraphs
Use asides for important notes, tips, cautions, and references in documentation
Provide runnable, minimal code examples that work as-is in documentation
Prefer CLI-first examples and show file layout when helpful in documentation
Label code blocks with titles for context (e.g., 'Terminal', 'main.ts') in documentation
Keep code block annotations brief and purposeful - annotate only what matters
Use consistent variable and file names across a documentation page
Use descriptive link text in documentation (e.g., 'See permission flags' not 'click here')
Prefer relative links for internal documentation pages and include anchors for section references
Reference APIs consistently using backticks for code, file names, CLI flags, and endpoints
Use backticks for code, file names, CLI flags, and endpoints in documentation
Use lists for options and features in documentation; tables only when comparisons are cleare...
Files:
src/content/docs/authenticate/m2m/api-keys.mdx
🧠 Learnings (47)
📓 Common learnings
Learnt from: saif-at-scalekit
Repo: scalekit-inc/developer-docs PR: 424
File: public/api/scalekit.scalar.json:3451-3457
Timestamp: 2026-02-10T05:32:59.967Z
Learning: In scalekit-inc/developer-docs, the file public/api/scalekit.scalar.json is a generated OpenAPI artifact; reviewers should avoid direct edits. For inconsistencies (e.g., the /api/v1/permissions "type" query param description vs. enum), handle short-term via release/PR notes and track long-term fixes in the generator or source templates rather than modifying the generated JSON.
Learnt from: AkshayParihar33
Repo: scalekit-inc/developer-docs PR: 415
File: src/content/docs/authenticate/fsa/multiapp/native-app.mdx:72-179
Timestamp: 2026-02-02T05:55:51.251Z
Learning: In the `src/content/docs/authenticate/fsa/multiapp/` directory, the multi-app authentication documentation (native-app.mdx, single-page-app.mdx, web-app.mdx, overview.mdx) currently uses conceptual shell/curl examples instead of multi-language SDK code examples because the Scalekit SDKs have not yet been built/updated for multi-app functionality. Once the SDKs are ready, these files should be updated to include all 4 languages (Node.js, Python, Go, Java) using `<Tabs syncKey="tech-stack">`.
Learnt from: CR
Repo: scalekit-inc/developer-docs PR: 0
File: .cursorrules:0-0
Timestamp: 2026-01-13T12:46:55.260Z
Learning: Keep documentation accurate and up-to-date with product changes, updating examples when APIs change
📚 Learning: 2026-02-02T05:55:51.251Z
Learnt from: AkshayParihar33
Repo: scalekit-inc/developer-docs PR: 415
File: src/content/docs/authenticate/fsa/multiapp/native-app.mdx:72-179
Timestamp: 2026-02-02T05:55:51.251Z
Learning: In the `src/content/docs/authenticate/fsa/multiapp/` directory, the multi-app authentication documentation (native-app.mdx, single-page-app.mdx, web-app.mdx, overview.mdx) currently uses conceptual shell/curl examples instead of multi-language SDK code examples because the Scalekit SDKs have not yet been built/updated for multi-app functionality. Once the SDKs are ready, these files should be updated to include all 4 languages (Node.js, Python, Go, Java) using `<Tabs syncKey="tech-stack">`.
Applied to files:
src/content/docs/authenticate/m2m/api-keys.mdx
📚 Learning: 2026-01-13T12:46:55.260Z
Learnt from: CR
Repo: scalekit-inc/developer-docs PR: 0
File: .cursorrules:0-0
Timestamp: 2026-01-13T12:46:55.260Z
Learning: Applies to **/*.mdx : Include context comments explaining what's happening in code: '// Extract encrypted tokens from request cookies', '// Decrypt the access token before validation'
Applied to files:
src/content/docs/authenticate/m2m/api-keys.mdx
📚 Learning: 2026-01-13T12:46:55.260Z
Learnt from: CR
Repo: scalekit-inc/developer-docs PR: 0
File: .cursorrules:0-0
Timestamp: 2026-01-13T12:46:55.260Z
Learning: Applies to **/*.mdx : Include configuration comments in code examples: '// Get the signing secret from Scalekit dashboard > Interceptors tab'
Applied to files:
src/content/docs/authenticate/m2m/api-keys.mdx
📚 Learning: 2026-01-13T12:46:55.260Z
Learnt from: CR
Repo: scalekit-inc/developer-docs PR: 0
File: .cursorrules:0-0
Timestamp: 2026-01-13T12:46:55.260Z
Learning: Applies to **/*.mdx : Use present tense for descriptions: 'Scalekit handles the complex authentication flow', 'The SDK provides methods to refresh tokens'
Applied to files:
src/content/docs/authenticate/m2m/api-keys.mdx
📚 Learning: 2026-01-13T12:46:55.260Z
Learnt from: CR
Repo: scalekit-inc/developer-docs PR: 0
File: .cursorrules:0-0
Timestamp: 2026-01-13T12:46:55.260Z
Learning: Applies to **/*.mdx : Use action verbs in section headings: 'Store session tokens securely', 'Validate the state parameter', 'Exchange authorization code for tokens'
Applied to files:
src/content/docs/authenticate/m2m/api-keys.mdx
📚 Learning: 2026-02-10T05:32:59.967Z
Learnt from: saif-at-scalekit
Repo: scalekit-inc/developer-docs PR: 424
File: public/api/scalekit.scalar.json:3451-3457
Timestamp: 2026-02-10T05:32:59.967Z
Learning: In scalekit-inc/developer-docs, the file public/api/scalekit.scalar.json is a generated OpenAPI artifact; reviewers should avoid direct edits. For inconsistencies (e.g., the /api/v1/permissions "type" query param description vs. enum), handle short-term via release/PR notes and track long-term fixes in the generator or source templates rather than modifying the generated JSON.
Applied to files:
src/content/docs/authenticate/m2m/api-keys.mdx
📚 Learning: 2026-01-13T12:47:52.148Z
Learnt from: CR
Repo: scalekit-inc/developer-docs PR: 0
File: .cursor/rules/deno-docs-style.mdc:0-0
Timestamp: 2026-01-13T12:47:52.148Z
Learning: Applies to **/*.{md,mdx} : Set frontmatter title in sentence case with a clear outcome; description in one sentence (≤160 chars); sidebar.label as shorter form of title; enable tableOfContents on longer pages
Applied to files:
src/content/docs/authenticate/m2m/api-keys.mdx
📚 Learning: 2026-01-13T12:47:52.148Z
Learnt from: CR
Repo: scalekit-inc/developer-docs PR: 0
File: .cursor/rules/deno-docs-style.mdc:0-0
Timestamp: 2026-01-13T12:47:52.148Z
Learning: Applies to **/*.{md,mdx} : Keep sidebar labels concise (1–3 words), use sentence case, and focus on outcomes or objects
Applied to files:
src/content/docs/authenticate/m2m/api-keys.mdx
📚 Learning: 2026-01-13T12:48:19.565Z
Learnt from: CR
Repo: scalekit-inc/developer-docs PR: 0
File: .cursor/rules/expressive-code.mdc:0-0
Timestamp: 2026-01-13T12:48:19.565Z
Learning: Applies to **/*.{md,mdx} : Use sentence case for headings near code examples (e.g., 'Authenticate users')
Applied to files:
src/content/docs/authenticate/m2m/api-keys.mdx
📚 Learning: 2026-01-30T18:20:07.851Z
Learnt from: AkshayParihar33
Repo: scalekit-inc/developer-docs PR: 415
File: src/content/docs/authenticate/fsa/multiapp/native-app.mdx:1-6
Timestamp: 2026-01-30T18:20:07.851Z
Learning: In the scalekit-inc/developer-docs repository, MDX files under `src/content/docs/authenticate/fsa/multiapp/` do not use `order` or `tags` fields in their frontmatter. Ordering and grouping are managed centrally in `src/configs/sidebar.config.ts`.
Applied to files:
src/content/docs/authenticate/m2m/api-keys.mdx
📚 Learning: 2026-01-13T12:46:55.260Z
Learnt from: CR
Repo: scalekit-inc/developer-docs PR: 0
File: .cursorrules:0-0
Timestamp: 2026-01-13T12:46:55.260Z
Learning: Applies to **/*.mdx : Use transition phrases between sections: 'After the user authenticates...', 'Once the state is validated...', 'Let's take a look at how to...'
Applied to files:
src/content/docs/authenticate/m2m/api-keys.mdx
📚 Learning: 2026-01-13T12:47:12.462Z
Learnt from: CR
Repo: scalekit-inc/developer-docs PR: 0
File: .cursor/rules/browsecentral-labels.mdc:0-0
Timestamp: 2026-01-13T12:47:12.462Z
Learning: Applies to **/*.{yml,yaml,md,mdx} : BrowseCentral labels should use 'Action + Object' pattern (e.g., 'Invite users', 'Restrict sign-up', 'Set up SCIM')
Applied to files:
src/content/docs/authenticate/m2m/api-keys.mdx
📚 Learning: 2026-01-13T12:46:55.260Z
Learnt from: CR
Repo: scalekit-inc/developer-docs PR: 0
File: .cursorrules:0-0
Timestamp: 2026-01-13T12:46:55.260Z
Learning: Applies to **/*.mdx : Use consistent SDK variable naming: Node.js='scalekit', Python='scalekit_client', Go='scalekitClient', Java='scalekitClient'
Applied to files:
src/content/docs/authenticate/m2m/api-keys.mdx
📚 Learning: 2026-02-18T02:55:23.285Z
Learnt from: CR
Repo: scalekit-inc/developer-docs PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-02-18T02:55:23.285Z
Learning: Applies to **/*.{md,mdx} : Use SDK variable names: Node.js `scalekit`, Python `scalekit_client`, Go `scalekitClient`, Java `scalekitClient`
Applied to files:
src/content/docs/authenticate/m2m/api-keys.mdx
📚 Learning: 2026-01-13T12:46:55.260Z
Learnt from: CR
Repo: scalekit-inc/developer-docs PR: 0
File: .cursorrules:0-0
Timestamp: 2026-01-13T12:46:55.260Z
Learning: Applies to **/*.mdx : Use future tense for results: 'This will redirect users to...', 'You'll receive a JWT containing...', 'Scalekit returns an authorization code'
Applied to files:
src/content/docs/authenticate/m2m/api-keys.mdx
📚 Learning: 2026-01-13T12:47:33.407Z
Learnt from: CR
Repo: scalekit-inc/developer-docs PR: 0
File: .cursor/rules/comment-standards.mdc:0-0
Timestamp: 2026-01-13T12:47:33.407Z
Learning: Applies to **/*.{js,ts,tsx,jsx,py,java,cs,go,cpp,c,rb,php,swift,kt,scala,rs,m,mm,groovy} : Add comments when fixing bugs - document bug fixes with context about the issue, reference issue trackers and bug reports, and explain workarounds and their limitations
Applied to files:
src/content/docs/authenticate/m2m/api-keys.mdx
📚 Learning: 2026-01-13T12:46:55.260Z
Learnt from: CR
Repo: scalekit-inc/developer-docs PR: 0
File: .cursorrules:0-0
Timestamp: 2026-01-13T12:46:55.260Z
Learning: Applies to **/*.mdx : Include todo/next step comments in code examples: '// TODO: Store user session (next guide covers this)', '// Next step: Create a session and log in the user'
Applied to files:
src/content/docs/authenticate/m2m/api-keys.mdx
📚 Learning: 2026-01-13T12:48:11.566Z
Learnt from: CR
Repo: scalekit-inc/developer-docs PR: 0
File: .cursor/rules/documentation-guide.mdc:0-0
Timestamp: 2026-01-13T12:48:11.566Z
Learning: Applies to **/*.{md,mdx} : Ensure code examples reflect current APIs and are tested when possible
Applied to files:
src/content/docs/authenticate/m2m/api-keys.mdx
📚 Learning: 2026-01-13T12:46:55.260Z
Learnt from: CR
Repo: scalekit-inc/developer-docs PR: 0
File: .cursorrules:0-0
Timestamp: 2026-01-13T12:46:55.260Z
Learning: Applies to **/*.mdx : Always include error handling in code examples showing both success and error paths
Applied to files:
src/content/docs/authenticate/m2m/api-keys.mdx
📚 Learning: 2026-02-18T02:55:23.285Z
Learnt from: CR
Repo: scalekit-inc/developer-docs PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-02-18T02:55:23.285Z
Learning: Applies to **/*.{md,mdx} : Include security comments in code examples explaining threats and security implications
Applied to files:
src/content/docs/authenticate/m2m/api-keys.mdx
📚 Learning: 2026-01-13T12:48:11.566Z
Learnt from: CR
Repo: scalekit-inc/developer-docs PR: 0
File: .cursor/rules/documentation-guide.mdc:0-0
Timestamp: 2026-01-13T12:48:11.566Z
Learning: Applies to **/*.{md,mdx} : Prefer comments explaining intent in code examples, not restating code
Applied to files:
src/content/docs/authenticate/m2m/api-keys.mdx
📚 Learning: 2026-01-13T12:47:33.407Z
Learnt from: CR
Repo: scalekit-inc/developer-docs PR: 0
File: .cursor/rules/comment-standards.mdc:0-0
Timestamp: 2026-01-13T12:47:33.407Z
Learning: Applies to **/*.{js,ts,tsx,jsx,py,java,cs,go,cpp,c,rb,php,swift,kt,scala,rs,m,mm,groovy} : Explain unidiomatic code in comments - comment on code that might seem unnecessary or redundant and document why you chose a specific pattern over more common alternatives, especially when it deviates from team conventions
Applied to files:
src/content/docs/authenticate/m2m/api-keys.mdx
📚 Learning: 2026-01-13T12:46:55.260Z
Learnt from: CR
Repo: scalekit-inc/developer-docs PR: 0
File: .cursorrules:0-0
Timestamp: 2026-01-13T12:46:55.260Z
Learning: Applies to **/*.mdx : Always include security comments in security-related code with pattern: '// Security: ALWAYS verify requests are from Scalekit before processing'
Applied to files:
src/content/docs/authenticate/m2m/api-keys.mdx
📚 Learning: 2026-01-13T12:47:33.407Z
Learnt from: CR
Repo: scalekit-inc/developer-docs PR: 0
File: .cursor/rules/comment-standards.mdc:0-0
Timestamp: 2026-01-13T12:47:33.407Z
Learning: Applies to **/*.{js,ts,tsx,jsx,py,java,cs,go,cpp,c,rb,php,swift,kt,scala,rs,m,mm,groovy} : Use comments to mark incomplete implementations - use standard formats for TODO, FIXME, and NOTE comments with context about what needs to be done and reference issue trackers when possible
Applied to files:
src/content/docs/authenticate/m2m/api-keys.mdx
📚 Learning: 2026-01-13T12:47:33.407Z
Learnt from: CR
Repo: scalekit-inc/developer-docs PR: 0
File: .cursor/rules/comment-standards.mdc:0-0
Timestamp: 2026-01-13T12:47:33.407Z
Learning: Applies to **/*.{js,ts,tsx,jsx,py,java,cs,go,cpp,c,rb,php,swift,kt,scala,rs,m,mm,groovy} : Always document public APIs with function/class comments - explain the purpose, parameters, return values, and exceptions; include usage examples for complex functions
Applied to files:
src/content/docs/authenticate/m2m/api-keys.mdx
📚 Learning: 2026-01-13T12:48:19.565Z
Learnt from: CR
Repo: scalekit-inc/developer-docs PR: 0
File: .cursor/rules/expressive-code.mdc:0-0
Timestamp: 2026-01-13T12:48:19.565Z
Learning: Applies to **/*.{md,mdx} : Use Expressive Code consistently across all documentation pages, preferring Starlight's `<Code>` component for rich features (titles, markers, accurate syntax highlighting) and dynamic snippets over fenced code blocks
Applied to files:
src/content/docs/authenticate/m2m/api-keys.mdx
📚 Learning: 2026-01-13T12:48:19.565Z
Learnt from: CR
Repo: scalekit-inc/developer-docs PR: 0
File: .cursor/rules/expressive-code.mdc:0-0
Timestamp: 2026-01-13T12:48:19.565Z
Learning: Applies to **/*.mdx : Import `{ Code }` from `astrojs/starlight/components` once per `.mdx` file, placing the import below frontmatter
Applied to files:
src/content/docs/authenticate/m2m/api-keys.mdx
📚 Learning: 2026-01-13T12:48:19.565Z
Learnt from: CR
Repo: scalekit-inc/developer-docs PR: 0
File: .cursor/rules/expressive-code.mdc:0-0
Timestamp: 2026-01-13T12:48:19.565Z
Learning: Applies to **/*.mdx : Prefer `<Code>` component when code snippets need any of: filename/title, text markers, programmatic/dynamic content, or consistent theming across tabs
Applied to files:
src/content/docs/authenticate/m2m/api-keys.mdx
📚 Learning: 2026-01-13T12:46:55.260Z
Learnt from: CR
Repo: scalekit-inc/developer-docs PR: 0
File: .cursorrules:0-0
Timestamp: 2026-01-13T12:46:55.260Z
Learning: Applies to astro.config.mjs : Expressive Code collapsible sections plugin must be enabled in `astro.config.mjs`
Applied to files:
src/content/docs/authenticate/m2m/api-keys.mdx
📚 Learning: 2026-01-13T12:48:19.565Z
Learnt from: CR
Repo: scalekit-inc/developer-docs PR: 0
File: .cursor/rules/expressive-code.mdc:0-0
Timestamp: 2026-01-13T12:48:19.565Z
Learning: Applies to **/*.mdx : Provide a `title` prop to the `<Code>` component when the snippet represents a file
Applied to files:
src/content/docs/authenticate/m2m/api-keys.mdx
📚 Learning: 2026-01-13T12:46:55.260Z
Learnt from: CR
Repo: scalekit-inc/developer-docs PR: 0
File: .cursorrules:0-0
Timestamp: 2026-01-13T12:46:55.260Z
Learning: Applies to **/*.mdx : Use 'collapse={lines}' to hide imports, setup, and boilerplate code in code blocks
Applied to files:
src/content/docs/authenticate/m2m/api-keys.mdx
📚 Learning: 2026-01-13T12:46:55.260Z
Learnt from: CR
Repo: scalekit-inc/developer-docs PR: 0
File: .cursorrules:0-0
Timestamp: 2026-01-13T12:46:55.260Z
Learning: Applies to **/*.mdx : Use 'title' attribute in code blocks to show framework names: 'Express.js', 'Flask', 'Gin', 'Spring Boot'
Applied to files:
src/content/docs/authenticate/m2m/api-keys.mdx
📚 Learning: 2026-01-13T12:48:19.565Z
Learnt from: CR
Repo: scalekit-inc/developer-docs PR: 0
File: .cursor/rules/expressive-code.mdc:0-0
Timestamp: 2026-01-13T12:48:19.565Z
Learning: Applies to **/*.{md,mdx} : Keep code examples minimal and runnable; avoid extraneous comments and explain intent above or below the block instead of inline
Applied to files:
src/content/docs/authenticate/m2m/api-keys.mdx
📚 Learning: 2026-01-13T12:46:55.260Z
Learnt from: CR
Repo: scalekit-inc/developer-docs PR: 0
File: .cursorrules:0-0
Timestamp: 2026-01-13T12:46:55.260Z
Learning: Applies to **/*.mdx : Use collapsible sections in introduction for sequence diagrams, video demonstrations, data models, and JSON examples with appropriate icons
Applied to files:
src/content/docs/authenticate/m2m/api-keys.mdx
📚 Learning: 2026-01-13T12:48:11.566Z
Learnt from: CR
Repo: scalekit-inc/developer-docs PR: 0
File: .cursor/rules/documentation-guide.mdc:0-0
Timestamp: 2026-01-13T12:48:11.566Z
Learning: Applies to **/*.{md,mdx} : Use diagrams when they improve understanding; keep them simple
Applied to files:
src/content/docs/authenticate/m2m/api-keys.mdx
📚 Learning: 2026-01-13T12:46:55.260Z
Learnt from: CR
Repo: scalekit-inc/developer-docs PR: 0
File: .cursorrules:0-0
Timestamp: 2026-01-13T12:46:55.260Z
Learning: Applies to **/*.mdx : Include use case comments explaining scenarios in code examples: '// Use case: Provision a workspace after a sales-assisted onboarding'
Applied to files:
src/content/docs/authenticate/m2m/api-keys.mdx
📚 Learning: 2026-01-13T12:47:52.148Z
Learnt from: CR
Repo: scalekit-inc/developer-docs PR: 0
File: .cursor/rules/deno-docs-style.mdc:0-0
Timestamp: 2026-01-13T12:47:52.148Z
Learning: Applies to **/*.{md,mdx} : Use outcome-focused headings that describe results, not categories (e.g., 'Run a script' not 'Scripts')
Applied to files:
src/content/docs/authenticate/m2m/api-keys.mdx
📚 Learning: 2026-01-13T12:47:12.462Z
Learnt from: CR
Repo: scalekit-inc/developer-docs PR: 0
File: .cursor/rules/browsecentral-labels.mdc:0-0
Timestamp: 2026-01-13T12:47:12.462Z
Learning: Applies to **/*.{yml,yaml,md,mdx} : BrowseCentral labels should be action-oriented - start with verbs when possible
Applied to files:
src/content/docs/authenticate/m2m/api-keys.mdx
📚 Learning: 2026-01-13T12:47:52.148Z
Learnt from: CR
Repo: scalekit-inc/developer-docs PR: 0
File: .cursor/rules/deno-docs-style.mdc:0-0
Timestamp: 2026-01-13T12:47:52.148Z
Learning: Applies to **/*.{md,mdx} : Avoid gerunds in headings when an imperative works - prefer 'Configure proxies' over 'Configuring proxies'
Applied to files:
src/content/docs/authenticate/m2m/api-keys.mdx
📚 Learning: 2026-01-13T12:48:11.566Z
Learnt from: CR
Repo: scalekit-inc/developer-docs PR: 0
File: .cursor/rules/documentation-guide.mdc:0-0
Timestamp: 2026-01-13T12:48:11.566Z
Learning: Applies to **/*.{md,mdx} : Use active voice and imperative mood for steps and procedures in documentation
Applied to files:
src/content/docs/authenticate/m2m/api-keys.mdx
📚 Learning: 2026-01-13T12:46:55.260Z
Learnt from: CR
Repo: scalekit-inc/developer-docs PR: 0
File: .cursorrules:0-0
Timestamp: 2026-01-13T12:46:55.260Z
Learning: Applies to **/*.mdx : Use action-oriented headings in step-by-step guides within Steps components
Applied to files:
src/content/docs/authenticate/m2m/api-keys.mdx
📚 Learning: 2026-01-13T12:47:12.462Z
Learnt from: CR
Repo: scalekit-inc/developer-docs PR: 0
File: .cursor/rules/browsecentral-labels.mdc:0-0
Timestamp: 2026-01-13T12:47:12.462Z
Learning: Applies to **/*.{yml,yaml,md,mdx} : BrowseCentral labels should avoid weak verbs: 'Enable', 'Allow', 'Provide', 'Support'
Applied to files:
src/content/docs/authenticate/m2m/api-keys.mdx
📚 Learning: 2026-01-13T12:46:55.260Z
Learnt from: CR
Repo: scalekit-inc/developer-docs PR: 0
File: .cursorrules:0-0
Timestamp: 2026-01-13T12:46:55.260Z
Learning: Applies to **/*.mdx : Use direct instruction writing style with phrases like 'This guide shows you how to...' and 'Create an authorization URL to...'
Applied to files:
src/content/docs/authenticate/m2m/api-keys.mdx
📚 Learning: 2026-02-18T02:55:23.285Z
Learnt from: CR
Repo: scalekit-inc/developer-docs PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-02-18T02:55:23.285Z
Learning: Applies to **/*.{md,mdx} : Show both success and error paths in code examples
Applied to files:
src/content/docs/authenticate/m2m/api-keys.mdx
📚 Learning: 2026-01-30T18:18:50.883Z
Learnt from: AkshayParihar33
Repo: scalekit-inc/developer-docs PR: 415
File: src/content/docs/authenticate/fsa/multiapp/manage-apps.mdx:31-49
Timestamp: 2026-01-30T18:18:50.883Z
Learning: In all Scalekit documentation files (MDX), treat the terms 'Applications', 'Single Page Application (SPA)', 'Native Application', and 'Web Application' as proper nouns and preserve their capitalization in headings and body text. Ensure these terms remain capitalized even when used in sentence case or within prose.
Applied to files:
src/content/docs/authenticate/m2m/api-keys.mdx
📚 Learning: 2026-02-04T12:47:16.544Z
Learnt from: saif-at-scalekit
Repo: scalekit-inc/developer-docs PR: 412
File: src/content/docs/dev-kit/tools/scalekit-dryrun.mdx:1-23
Timestamp: 2026-02-04T12:47:16.544Z
Learning: In scalekit-inc/developer-docs, the MDX frontmatter field order is required only when the sidebar configuration points to a directory (for auto-generation). If the sidebar.config.ts references a specific file path, the order field is not required. Apply this check to all MDX files under src/content/docs: if a file contributes to an auto-generated sidebar (directory path), ensure order is present; if it’s linked to a concrete file, order can be omitted. Use sidebar.config.ts to determine whether a given MDX file falls under directory-based vs file-specific sidebar references.
Applied to files:
src/content/docs/authenticate/m2m/api-keys.mdx
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@src/content/docs/authenticate/m2m/api-keys.mdx`:
- Around line 674-697: The Java listing lacks error handling: wrap calls to
scalekitClient.tokens().list (the initial call, the paginated call using
response.getNextPageToken(), and the filtered call that returns userTokens) in a
try/catch block that catches Exception (or a more specific client exception),
print a clear error message and exception details (e.g., System.err.println or
logging with e.printStackTrace()) in the catch, and keep the existing
success-path code that iterates over ListTokensResponse and Token inside the try
block so both success and error paths are shown.
---
Duplicate comments:
In `@src/content/docs/authenticate/m2m/api-keys.mdx`:
- Around line 791-793: The middleware examples call scalekit.token.validateToken
but are missing the required standardized security comment; add the prescribed
security comment block immediately above each validateToken invocation in the
Node.js example (near scalekit.token.validateToken), and likewise add the same
comment in the Python, Go, and Java middleware examples where validateToken (or
equivalent token validation call) is used so the security rationale and audit
info are present for each validation site.
- Around line 1-16: The frontmatter is missing tableOfContents and the sidebar
label uses Title Case; add a top-level frontmatter key tableOfContents: true and
change the sidebar label value from "Add API Keys" to sentence-case "Add API
keys" (update the 'tableOfContents' frontmatter entry and the 'sidebar: label'
field in this file so the page renders a TOC and follows the sentence-case
guideline).
- Around line 124-137: Add concise use-case and next-step/TODO comments around
the token creation snippet: before scalekit.token.createToken include a one-line
comment describing when to use a CI/CD pipeline token (e.g., automated
deployment or CI jobs), and after extracting opaqueToken and tokenId add
comments stating that opaqueToken must be stored securely (cannot be retrieved
later) and tokenId is for management operations; also add a TODO comment
suggesting rotating the token, storing it in a secret manager, and linking to
the equivalent examples for Python, Go, Java and the user-scoped token snippets
so readers know next steps and where to find language-specific variants.
- Around line 179-193: The Java example omits the description parameter when
calling scalekitClient.tokens().create; update the call to include a description
string (matching Node/Python/Go examples) so the created token has a
human-readable description. Edit the snippet around
scalekitClient.tokens().create(organizationId) in the method that returns
CreateTokenResponse so it passes the description argument, and leave the
subsequent uses of response.getToken() and response.getTokenId() unchanged.
- Line 117: Change the noun headings "Organization-scoped API key" and
"User-scoped API key" to action-oriented headings that start with a verb (e.g.,
"Create organization-scoped API key" and "Create user-scoped API key") so the
token creation sections follow the action-oriented heading guideline; update
both heading occurrences ("Organization-scoped API key" and "User-scoped API
key") in the document.
- Around line 308-323: Add the required security comment immediately above the
token validation call(s) to follow the security comment pattern; specifically
insert the standard comment before scalekit.token.validateToken(opaqueToken) in
this Node.js snippet and mirror the same comment placement for the other
language examples (Python/Go/Java) referenced, so that each validation call is
preceded by the security annotation; keep exception handling using
ScalekitValidateTokenFailureException and existing variables (opaqueToken,
result.tokenInfo) unchanged, only add the comment line(s) in front of the
validateToken invocation.
- Around line 60-68: Replace the fenced JavaScript block with the <Code>
component from `@astrojs/starlight/components` to support title/collapse metadata:
import the Code component and wrap the ScalekitClient example using <Code
language="javascript" title="Express.js" collapse={true}> containing the same
code that constructs ScalekitClient (refer to the ScalekitClient constructor
call and the three process.env args) so the snippet renders with the preferred
component and preserves title/collapse behavior.
- Around line 27-45: Wrap the existing sequence diagram code block (the fenced
block containing "d2 pad=36" and "shape: sequence_diagram") in a collapsible
HTML details element: add a <details> with a <summary> that includes the
suggested icon (e.g., "✏️ Suggested wrapper") above the opening triple-backtick
and close the details after the closing triple-backtick, preserving the exact
diagram content and fence markers so rendering is unchanged when expanded.
- Line 958: This doc ending after the sentence "You now have everything you need
to issue, validate, and manage API keys in your application." is missing the
required STYLE-CHECK footer; append a single line at the end of the file reading
"STYLE-CHECK: [PASSED | TODO]" (choose PASSED if style checks are complete,
otherwise TODO) so the document conforms to the STYLE-CHECK requirement.
- Around line 57-68: Add brief configuration-context comments above each
SDK/client initialization so readers know where credentials come from and how to
set them: in the Node snippet add comments above the ScalekitClient
instantiation (and the scalekit const) explaining that
process.env.SCALEKIT_ENVIRONMENT_URL, SCALEKIT_CLIENT_ID, and
SCALEKIT_CLIENT_SECRET are environment variables populated from the Scalekit
dashboard or CI secrets; do the same for the equivalent client/class
instantiations in the Python, Go, and Java examples, mentioning how to obtain
the credentials and recommended storage (env vars or secrets manager).
- Around line 21-23: Update the opening paragraphs to fix grammar and
consistency: change "gives you" to "give you", replace "Organizational or User
Level" with "organization- or user-level", normalize "API Keys" to "API keys",
and hyphenate "client side" to "client-side"; ensure the sentence using "API
keys" and "client-side" reads smoothly after these replacements and keep
lowercase/Hyphenation consistent across the paragraph when referring to API keys
and client-side validation.
- Line 954: The "Set expiry for time-limited access" best-practice references an
expiry parameter but lacks an example; add a short code snippet under that
bullet showing how to pass the expiry when creating an API key (e.g., call to
createApiKey / POST /v1/api-keys with an expiry field using an ISO-8601
timestamp or TTL seconds) and/or add a link to the API reference for
createApiKey so readers can see parameter details; update the line containing
"Set expiry for time-limited access" and the `expiry` mention to include this
example or the reference link.
|
|
||
| ```java | ||
| import com.scalekit.grpc.scalekit.v1.tokens.ListTokensResponse; | ||
| import com.scalekit.grpc.scalekit.v1.tokens.Token; | ||
|
|
||
| // List tokens for an organization | ||
| ListTokensResponse response = scalekitClient.tokens().list(organizationId, 10, null); | ||
|
|
||
| for (Token token : response.getTokensList()) { | ||
| System.out.println(token.getTokenId() + " " + token.getDescription()); | ||
| } | ||
|
|
||
| // Paginate through results | ||
| if (!response.getNextPageToken().isEmpty()) { | ||
| ListTokensResponse nextPage = scalekitClient.tokens().list( | ||
| organizationId, 10, response.getNextPageToken() | ||
| ); | ||
| } | ||
|
|
||
| // Filter tokens by user | ||
| ListTokensResponse userTokens = scalekitClient.tokens().list( | ||
| organizationId, "usr_12345", 10, null | ||
| ); | ||
| ``` |
There was a problem hiding this comment.
Add error handling to Java list tokens example.
The Node.js, Python, and Go examples include error handling, but the Java example lacks a try/catch block. Per coding guidelines, all code examples should show both success and error paths.
✏️ Suggested fix
+try {
// List tokens for an organization
ListTokensResponse response = scalekitClient.tokens().list(organizationId, 10, null);
for (Token token : response.getTokensList()) {
System.out.println(token.getTokenId() + " " + token.getDescription());
}
// Paginate through results
if (!response.getNextPageToken().isEmpty()) {
ListTokensResponse nextPage = scalekitClient.tokens().list(
organizationId, 10, response.getNextPageToken()
);
}
// Filter tokens by user
ListTokensResponse userTokens = scalekitClient.tokens().list(
organizationId, "usr_12345", 10, null
);
+} catch (Exception e) {
+ System.err.println("Failed to list tokens: " + e.getMessage());
+}🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@src/content/docs/authenticate/m2m/api-keys.mdx` around lines 674 - 697, The
Java listing lacks error handling: wrap calls to scalekitClient.tokens().list
(the initial call, the paginated call using response.getNextPageToken(), and the
filtered call that returns userTokens) in a try/catch block that catches
Exception (or a more specific client exception), print a clear error message and
exception details (e.g., System.err.println or logging with e.printStackTrace())
in the catch, and keep the existing success-path code that iterates over
ListTokensResponse and Token inside the try block so both success and error
paths are shown.
Python SDK's token.py dropped .with_call so methods now return plain proto response objects instead of (response, call) tuples. Update all Python code examples in the API keys guide to remove [0] indexing.
Summary by CodeRabbit
Documentation
Navigation
Chores